使用sortedArrayUsingComparator对NSArray进行排序

时间:2014-09-10 15:16:20

标签: sorting swift nsarray

Objective-C我可以使用以下声明对NSArray进行排序:

NSArray *sortedArray = [persons sortedArrayUsingComparator:^NSComparisonResult(Person *p1, Person *p2) {
    return [p1.name compare:p2.name];
}];

我无法使用 Swift 重现相同的声明。我发现只是使用Array

5 个答案:

答案 0 :(得分:36)

您可以使用Swift's built in sort functions或者,因为Swift数组被桥接到NSArray,您可以直接从swift调用sortedArrayUsingComparator

使用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&#39; s 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
}

答案 1 :(得分:14)

没有必要避免使用Swift Array

它与NSArray在两个方向上都是桥接的,因此对于更安全的代码,最好只在需要与ObjC API互操作时使用Swift数组和桥接。 (在大多数导入的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 as NSArray来自ObjC API,则可能不需要persons部分。)

根据Person类的实现方式,使用描述符排序可以在后端产生更高效的排序。例如,如果它是一个核心数据管理对象,使用描述符进行排序可能会产生一个SQL查询,该查询在数据库中执行速度很快并且使用很少的内存,而使用比较器闭包进行排序需要从数据库中实例化每个对象,以便评估每个对象的关闭。

答案 2 :(得分:9)

所以试着用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")

答案 3 :(得分:0)

在Swift中,您可以使用新方法。尝试使用sorted方法而不是sortedArrayUsingComparator,就像这样...

var sortedArray = results.sorted {
    (obj1, obj2) -> Bool in 
    return obj1.count! > obj2.count!
}

答案 4 :(得分:0)

如果您有自定义对象并希望按日期排序

let sortedArray = self.posts.sorted {
            (obj1, obj2) -> Bool in
            return (obj1 as! PostModel).orderCancellionDate.compare( (obj2 as! PostModel).orderCancellionDate) == .orderedDescending
        }