如何使用比较器签名创建NSSortDescriptor?

时间:2017-03-10 19:19:31

标签: swift swift3 nssortdescriptor

我可以创建一个不区分大小写的字符串排序描述符,如下所示:

let titleSort = NSSortDescriptor(key: "title", ascending: true,
                                     selector: #selector(NSString.localizedCaseInsensitiveCompare))

我似乎无法弄清楚如何使用comparator签名:

class NSSortDescriptor {
  init(key: String?, ascending: Bool, comparator cmptr: @escaping Foundation.Comparator)
  ...
}

我是否必须从头开始创建一个新的比较器,或者String已经存在某些事情?

TIA

2 个答案:

答案 0 :(得分:4)

对此没有全局功能,因为比较器用于执行不内置的比较。它非常灵活,因为它允许您比较两种不同类型的对象,并准确定义您希望它们如何排序。在一个非常简单的演示如何对这些进行排序的过程中,我创建了一个示例,我首先检查传入的两个对象是否都是String,如果不是,我只是将它们视为应该在同一个地方进行排序水平。否则我按字母顺序排序(不区分大小写,因为我把它们变成小写)。显然,根据您预期需要排序的内容,您可以根据需要使其变得复杂:

let descriptor = NSSortDescriptor(key: "title", ascending: true) { (string1, string2) -> ComparisonResult in
        guard let s1 = string1 as? String, let s2 = string2 as? String else {
            return ComparisonResult.orderedSame
        }
        if s1.lowercased() < s2.lowercased() {
            return ComparisonResult.orderedAscending
        } else if s1.lowercased() == s2.lowercased() {
            return ComparisonResult.orderedSame
        } else {
            return ComparisonResult.orderedDescending
        }
    }

答案 1 :(得分:1)

示例:

class C : NSObject {
    var id = 0
}

let desc = NSSortDescriptor(key: "id", ascending: true) { // comparator function
    id1, id2 in
    if (id1 as! Int) < (id2 as! Int) { return .orderedAscending }
    if (id1 as! Int) > (id2 as! Int) { return .orderedDescending }
    return .orderedSame
}

// test:

let c1 = C(); let c2 = C(); let c3 = C()
c1.id = 100; c2.id = 50; c3.id = 25
let arr = [c1,c2,c3]
let arr2 = (arr as NSArray).sortedArray(using: [desc])