Dans mon code, j'ai une structure comme celle-ci:
struct Object {
var name: String
var count: Int
Je suis en train de créer un tableau de 10 objets avec des noms aléatoires et des nombres aléatoires.
Existe-t-il un moyen simple de
a) les trier par ordre alphabétique
b) les trier numériquement par ordre croissant
Fondamentalement, il y aura un tableau comme ceci: [Object1, Object2, Object3]
. Chaque objet a un attribut name
et count
, et je veux que les objets de cette liste soient triés via ces deux attributs.
Solution dans Swift2 (en utilisant cette solution: StackOverflow) :
Object.sort{
if $0.name != $1.name {
return $0.name < $1.name
}
else {
//suits are the same
return $0.count < $1.count
}
}
Cependant, cela a été renommé sorted(by: )
dans Swift3, et je ne quitte pas comment faire.
Si vous souhaitez trier par ordre alphabétique puis numérique, vous pouvez:
var array = ["A2", "B7", "A4", "C3", "A1", "A10"]
array.sort { $0.compare($1, options: .numeric) == .orderedAscending }
Cela produit:
["A1", "A2", "A4", "A10", "B7", "C3"]
J'ai ajouté A10
à votre tableau, car sans lui, un simple tri alphabétique aurait suffi. Mais je suppose que vous vouliez A10
après A4
, auquel cas la comparaison numérique fera le travail pour vous.
Vous avez modifié l'exemple pour qu'il soit une structure avec deux propriétés. Dans ce cas, vous pouvez faire quelque chose comme:
struct Foo {
var name: String
var count: Int
}
var array = [
Foo(name:"A", count: 2),
Foo(name:"B", count: 7),
Foo(name:"A", count: 7),
Foo(name:"C", count: 3),
Foo(name:"A", count: 1),
Foo(name:"A", count: 10)
]
array.sort { (object1, object2) -> Bool in
if object1.name == object2.name {
return object1.count < object2.count
} else {
return object1.name < object2.name
}
}
Ou, plus concis:
array.sort { $0.name == $1.name ? $0.count < $1.count : $0.name < $1.name }
Ou
array.sort { ($0.name, $0.count) < ($1.name, $1.count) }
Remarquez, plutôt que de mettre cette logique dans la fermeture, je ferais en fait Foo
conforme à Comparable
:
struct Foo {
var name: String
var count: Int
}
extension Foo: Equatable {
static func ==(lhs: Foo, rhs: Foo) -> Bool {
return (lhs.name, lhs.count) == (rhs.name, rhs.count)
}
}
extension Foo: Comparable {
static func <(lhs: Foo, rhs: Foo) -> Bool {
return (lhs.name, lhs.count) < (rhs.name, rhs.count)
}
}
Cela maintient la logique de comparaison bien encapsulée dans le type Foo
, où elle appartient.
Ensuite, vous pouvez simplement faire ce qui suit pour trier sur place:
var array = ...
array.sort()
Ou, vous pouvez également retourner un nouveau tableau si vous ne souhaitez pas trier l'original en place:
let array = ...
let sortedArray = array.sorted()
Narusan, peut-être que cela vous aidera. Disons que vous avez un tableau avec vos objets struct appelé objArray, alors vous pouvez le classer par le code ci-dessous:
var objArray = [Object]()
objArray.append(Object(name:"Steve", count:0))
objArray.append(Object(name:"Alex", count:1))
objNameSorted = objArray.sorted (by: {$0.name < $1.name})
objNCountSorted = objArray.sorted (by: {$0.count < $1.count})
Vous pouvez toujours utiliser le raccourci pour sorted
:
objNameSorted = objArray.sorted { $0 < $1 }
Bien que moins lisible, il imite de plus près la syntaxe sort
.