【问题标题】:Sort NSArray with sortedArrayUsingComparator使用 sortedArrayUsingComparator 对 NSArray 进行排序
【发布时间】:2014-11-04 07:40:54
【问题描述】:

Objective-C 中,我可以使用以下语句对NSArray 进行排序:

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

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

【问题讨论】:

    标签: sorting swift nsarray


    【解决方案1】:

    您可以使用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
    }
    

    或者,使用NSArraysortedArrayUsingComparator

    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
    }
    

    【讨论】:

    • NSComparisonResult 现在是 ComparisonResult
    【解决方案2】:

    没有必要避免使用 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 类的实现方式,使用描述符进行排序可以在后端产生更有效的排序。例如,如果它是一个 Core Data 托管对象,使用描述符进行排序可能会产生一个 SQL 查询,该查询在数据库中执行速度很快并且使用很少的内存,而使用比较器闭包进行排序需要实例化数据库中的每个对象,以便针对每个对象评估闭包.

    【讨论】:

    • 非常感谢@rickster。这对我很有用。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多