J'ai un tableau de modèles qui a 2 propriétés:
1. Titre (chaîne)
2. selected (Bool)
Je veux les trier en fonction de la propriété selected
de manière à ce que cela se fasse par rapport à la séquence du tableau source. Par exemple, si tout est FALSE ou TRUE, il devrait y avoir la même sortie après la commande.
Mais si j'utilise le suivant, cela modifie le tri d'origine après les avoir classés en fonction de cette propriété BOOL.
< pre> XXXQue dois-je faire pour conserver la séquence d'origine?
MODIFIER 1:
L'ordre de tri du Titre
n'apparaît pas dans l'image. Peut-être que le serveur m'envoie 4 objets ayant le titre Z, Y, P, A. Donc, si tout est faux et une fois que je trie, ce devrait être comme Z faux, Y faux, P faux, A faux.
4 Réponses :
Vous avez besoin de
someArray = array.sorted (by:{ $0.selected && !$1.selected && <#Add more conditions #>})
triés (par
ne mute pas le tableau d'origine contrairement au sort
https://developer.apple.com/documentation/swift/array/1688499-sort
https://developer.apple. com / documentation / swift / array / 2296815 triés
Merci, voir mon EDIT
@RakeshaShastri étant || ou && est selon la logique dont l'op a besoin
@Sh_Khan il y a un if
. si cela correspond également aux besoins de l'OP, vous pourriez simplement avoir écrit array.sorted (par: <# What OP needs #>)
. Je ne vois aucune différence.
Vous devez utiliser la méthode sorted
au lieu de sort
;
let newArray = array.sorted { $0.selected && !$1.selected }
Fondamentalement, sort
trie dans le même tableau, trié
renvoie un nouveau tableau, sans changer l'original
Si vous souhaitez conserver la commande que vous recevez d'un serveur, je vous suggérerai de ne pas utiliser la méthode sort
ou triée
, car ils ne sont pas garantis de conserver l'ordre d'origine pour les clés du même ordre. Je vous recommanderai d'écrire votre propre fonction de tri:
[ Model(title: "a", selected: true), Model(title: "c", selected: true), Model(title: "a", selected: false), Model(title: "b", selected: false) ]
Si vous ne voulez pas créer une extension Comparable
à votre modèle (parce que par exemple , vous utilisez un ordre différent de ces modèles à quelques endroits), vous pouvez utiliser la méthode sorted
, mais fournir un bloc de tri différent:
struct Model { let title:String let selected:Bool } let array = [ Model(title: "a", selected: true), Model(title: "a", selected: false), Model(title: "b", selected: false), Model(title: "c", selected: true)] let newArray = array.sorted { (lhs, rhs) -> Bool in if lhs.selected == rhs.selected { return lhs.title < rhs.title } return lhs.selected } print(newArray)
et l'ordre de tri sera:
struct Model { let title:String let selected:Bool } let array = [ Model(title: "Z", selected: true), Model(title: "Z", selected: false), Model(title: "Y", selected: false), Model(title: "P", selected: false), Model(title: "A", selected: true), Model(title: "A", selected: false)] extension Array where Element == Model { func preserveSorted() -> [Model] { var selected:[Model] = [] var notSelected:[Model] = [] for model in self { if model.selected { selected.append(model) } else { notSelected.append(model) } } var output:[Model] = [] output.append(contentsOf: selected) output.append(contentsOf: notSelected) return output } } var newArray:[Model] = array.preserveSorted() print(newArray) /* output: [ Model(title: "Z", selected: true), Model(title: "A", selected: true), Model(title: "Z", selected: false), Model(title: "Y", selected: false), Model(title: "P", selected: false), Model(title: "A", selected: false) ] */
Merci, le titre ne vient pas en image. Peut-être que le serveur m'envoie 4 objets ayant le titre Z, Y, P, A. Donc, si tout est faux et une fois que je trie, cela devrait être comme Z faux, Y faux, P faux, A faux.
@NSPratik J'ai mis à jour ma réponse, pouvez-vous la vérifier?
Au lieu de trier, vous pouvez le faire plus efficacement en utilisant une opération de filtrage:
let newArray = array.stableSorted { return $0.selected == $1.selected || $0.selected }
Malheureusement, Array.sorted
ne garantit pas un tri stable, vous ne peut pas simplement trier par une propriété et s'attendre à ce que le tri d'origine soit conservé.
Vous pouvez cependant implémenter un tri stable facilement (par exemple https://stackoverflow.com/a/50545761/669586 )
Ensuite, vous pouvez simplement utiliser:
let newArray = array.stableSorted { let numeric1 = $0.selected ? 0 : 1 let numeric2 = $1.selected ? 0 : 1 return numeric1 <= numeric2 }
ou p>
let newArray = array.filter { $0.selected } + array.filter { !$0.selected }
Est-ce votre véritable code? Vous devriez voir un avertissement du compilateur «La constante 'someArray' est supposée avoir le type '()', ce qui peut être inattendu»
Je viens de placer un prototype
Ce que vous recherchez (apparemment) est une sorte «stable». Dans Swift 5, la méthode
sort ()
se trouve être stable, mais ce n'est pas garanti.Voir aussi Comment stabiliser le tri d'un tableau en swift? .