Objective-C
次のステートメントを使用してNSArray
をソートできます。
NSArray *sortedArray = [persons sortedArrayUsingComparator:^NSComparisonResult(Person *p1, Person *p2) {
return [p1.name compare:p2.name];
}];
Swiftで同じステートメントを再現することはできません。私が見つけたのは、Array
を使用することだけでした。
Swiftの組み込みソート関数 を使用するか、Swift配列がNSArray
にブリッジされているため、sortedArrayUsingComparator
を呼び出すことができます] Swift=直接。
Swiftのsorted
関数を使用する:
var sortedArray = sorted(persons) {
(obj1, obj2) in
// The downcast to Person is only needed if persons is an NSArray or a Swift Array of AnyObjects
let p1 = obj1 as Person
let p2 = obj2 as Person
return p1.name < p2.name
}
または、NSArray
のsortedArrayUsingComparator
を使用します。
var sortedArray = persons.sortedArrayUsingComparator {
(obj1, obj2) -> NSComparisonResult in
let p1 = obj1 as Person
let p2 = obj2 as Person
let result = p1.name.compare(p2.name)
return result
}
回避する必要はありませんSwift Array
。
NSArray
で双方向にブリッジされているため、よりタイプセーフなコードの場合は、Swift配列で作業し、ObjC APIとの相互運用に必要な場合にのみブリッジするのが最善です。また、ほとんどのインポートされたAPIでは、SwiftはNSArray
を[AnyObject]
に自動的に変換するため、頻繁にブリッジする必要さえありません。)
persons
配列が他のAPIから取得した[AnyObject]
であると仮定すると、最初に配列をキャストすることにより、他の回答と比較して型キャストの量を削減できます。
let sortedPersons = sorted(persons as [Person]) { $0.name < $1.name }
// sortedPersons has inferred type [Person]
また、コンパレータブロックはPerson
クラスの特定のプロパティでソートするためだけに使用しているため、ソート記述子を使用した方がよい場合があります。
let sortedPersons = (persons as NSArray).sortedArrayUsingDescriptors([
NSSortDescriptor(key: "name", ascending: true)
])
(persons
がObjC APIからのものである場合、persons as NSArray
部分は不要な場合があります。)
Person
クラスの実装方法に応じて、記述子を使用したソートは、バックエンドでより効率的なソートを生成できます。たとえば、コアデータ管理オブジェクトの場合、記述子を使用した並べ替えでは、データベースで高速に実行され、メモリをほとんど使用しないSQLクエリが生成されますが、コンパレータクロージャーを使用した並べ替えでは、それぞれに対してクロージャーを評価するためにデータベースからすべてのオブジェクトをインスタンス化する必要があります。
だから、Swiftで同じことを書いてみてください:
var sortedArray:NSArray =
persons.sortedArrayUsingComparator(){(p1:AnyObject!, p2:AnyObject!) -> NSComparisonResult in
if (p1 as Person).name > (p2 as Person).name {
return NSComparisonResult.OrderedDescending
}
if (p1 as Person).name < (p2 as Person).name {
return NSComparisonResult.OrderedAscending
}
return NSComparisonResult.OrderedAscending
}
テスト(プレイグラウンド):
class Person{
var name:String?
}
var p1:Person = Person()
p1.name = "a"
var p3:Person = Person()
p3.name = "c"
var p2:Person = Person()
p2.name = "b"
var persons:NSArray = [p1,p3,p2]
var sortedArray:NSArray = persons.sortedArrayUsingComparator(){
(p1:AnyObject!, p2:AnyObject!) -> NSComparisonResult in
if (p1 as Person).name > (p2 as Person).name {
return NSComparisonResult.OrderedDescending
}
if (p1 as Person).name < (p2 as Person).name {
return NSComparisonResult.OrderedAscending
}
return NSComparisonResult.OrderedAscending
}
for item:AnyObject in sortedArray{
println((item as Person).name)
}
出力:
Optional("a")
Optional("b")
Optional("c")
Swift新しいアプローチを使用できます。このようにsortedArrayUsingComparatorの代わりにsortedメソッドを使用してみてください...
var sortedArray = results.sorted {
(obj1, obj2) -> Bool in
return obj1.count! > obj2.count!
}
カスタムオブジェクトがあり、日付でソートしたい場合
let sortedArray = self.posts.sorted {
(obj1, obj2) -> Bool in
return (obj1 as! PostModel).orderCancellionDate.compare( (obj2 as! PostModel).orderCancellionDate) == .orderedDescending
}