[英]Sort NSArray with sortedArrayUsingComparator
In Objective-C
I can sort an NSArray
using this statement: 在
Objective-C
我可以使用以下语句对NSArray
进行排序:
NSArray *sortedArray = [persons sortedArrayUsingComparator:^NSComparisonResult(Person *p1, Person *p2) {
return [p1.name compare:p2.name];
}];
I'm unable to reproduce the same statement with Swift . 我无法用Swift重现相同的声明。 All I found was using
Array
. 我发现的只是使用
Array
。
You can either use Swift's built in sort functions or, since a Swift array is bridged to NSArray
you can call sortedArrayUsingComparator
from swift directly. 您可以使用Swift的内置排序函数,或者由于Swift数组桥接到
NSArray
您可以直接从swift调用sortedArrayUsingComparator
。
Using Swift's sorted
function: 使用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
}
Or, using NSArray
's sortedArrayUsingComparator
: 或者,使用
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
}
There's no need to avoid Swift Array
. 没有必要避免使用Swift
Array
。
It's bridged in both directions with NSArray
, so for more type-safe code it's best to do your work with Swift arrays and bridge only when needed for interoperating with ObjC APIs. 它使用
NSArray
在两个方向上进行桥接,因此对于更安全类型的代码,最好只在需要与ObjC API进行互操作时使用Swift数组和桥接。 (And in most imported APIs, Swift automatically converts NSArray
to [AnyObject]
, so you don't even need to bridge very often.) (在大多数导入的API中,Swift会自动将
NSArray
转换为[AnyObject]
,因此您甚至不需要经常桥接。)
Assuming the persons
array is an [AnyObject]
you got from other API, you can cut down on the amount of type casting relative to other answers by casting the array first: 假设
persons
数组是从其他API获得的[AnyObject]
,您可以通过首先强制转换数组来减少类型转换相对于其他答案的数量:
let sortedPersons = sorted(persons as [Person]) { $0.name < $1.name }
// sortedPersons has inferred type [Person]
Also, since you're using a comparator block only to sort on a specific property of your Person
class, you might do better to use sort descriptors: 此外,由于您仅使用比较器块对
Person
类的特定属性进行排序,因此最好使用排序描述符:
let sortedPersons = (persons as NSArray).sortedArrayUsingDescriptors([
NSSortDescriptor(key: "name", ascending: true)
])
(The persons as NSArray
part may not be necessary if persons
came from an ObjC API.) (如果
persons
来自ObjC API,则可能不需要persons as NSArray
部分persons
。)
Depending on how the Person
class is implemented, sorting with descriptors can produce a more efficient sort on the backend. 根据
Person
类的实现方式,使用描述符进行排序可以在后端生成更高效的排序。 For example, if it's a Core Data managed object, sorting with descriptors might produce a SQL query that executes fast in the database and uses little memory, while sorting with a comparator closure requires instantiating every object from the database just to evaluate the closure against each. 例如,如果它是一个核心数据管理对象,使用描述符进行排序可能会产生一个SQL查询,该查询在数据库中执行速度很快并且使用很少的内存,而使用比较器闭包进行排序则需要从数据库中实例化每个对象,只是为了评估每个对象的关闭。 。
So try just write the same with Swift: 所以试着用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
}
Test (Playground): 测试(游乐场):
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)
}
Output: 输出:
Optional("a")
Optional("b")
Optional("c")
In Swift you can use new approach. 在Swift中,您可以使用新方法。 Try to use sorted method instead sortedArrayUsingComparator like this...
尝试使用sorted方法而不是sortedArrayUsingComparator这样...
var sortedArray = results.sorted {
(obj1, obj2) -> Bool in
return obj1.count! > obj2.count!
}
in case you have custom object and want to sort by date 如果您有自定义对象并希望按日期排序
let sortedArray = self.posts.sorted {
(obj1, obj2) -> Bool in
return (obj1 as! PostModel).orderCancellionDate.compare( (obj2 as! PostModel).orderCancellionDate) == .orderedDescending
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.