用于将变量传递到排序闭包的swift语法

时间:2018-04-20 22:30:31

标签: swift

我有一个Swift语法问题。

我们说我有两种不同的阵列排序。

data:

但是,相反,我希望将VARIABLE提供到此闭包中以表示我可能想要排序的任何成员。所以我正在寻找更接近这个的东西:

...myArray.sorted(by: { $0.title < $1.title })
...myArray.sorted(by: { $0.dollar < $1.dollar })

使这项工作的正确语法是什么?

感谢。

1 个答案:

答案 0 :(得分:0)

取决于您可以容忍Objective-C代码的多少,答案范围从&#34;不可能&#34; (纯粹的斯威夫特),以及#34;不优雅的&#34; (Swift with Objective-C cast),#34;只使用Objective-C类型&#34; (即NSArray / NSMutableArray)。

由于Swift是一种静态发送的语言,动态功能并不是它的强项。 Swift 4增加了对关键路径的支持,允许你做这样的事情(取自Martin R's answer):

extension Array {
    mutating func sort<T: Comparable>(byKeyPath keyPath: KeyPath<Element, T>) {
        sort(by: { $0[keyPath: keyPath] < $1[keyPath: keyPath] })
    }
}

struct DataModel {
    var title: String
    var dollar: Double
}

var myArray = [DataModel(title: "A", dollar: 12), DataModel(title: "B", dollar: 10)]
let keyPath = \DataModel.dollar
myArray.sort(byKeyPath: keyPath)

但是没有办法从String构建关键路径。必须在编译时知道以确保类型安全。

这是Objective-C因其动态特性而擅长的东西:

@objcMembers
class DataModel: NSObject {
    var title: String
    var dollar: Double

    init(title: String, dollar: Double) {
        self.title = title
        self.dollar = dollar
    }
}

let myArray = [DataModel(title: "A", dollar: 12), DataModel(title: "B", dollar: 10)]

let sortKey = "title"
let sortDescriptors = [NSSortDescriptor(key: sortKey, ascending: true)]
let sortedArray = (myArray as NSArray).sortedArray(using: sortDescriptors) as! [DataModel]

当然,如果您将myArray保留为NSArray / NSMutableArray,则可以将所有投射留在后面。但是,你将坚定地进入Objective-C,无法访问Swift的Array函数,如mapfilter等。