【问题标题】:swift syntax for passing variables into sort closures将变量传递给排序闭包的快速语法
【发布时间】:2018-04-20 22:30:31
【问题描述】:

我有一个 Swift 语法问题。

假设我有两种不同的数组排序。

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

但是,相反,我想在这个闭包中输入一个 VARIABLE 来代表我可能想要排序的任何成员。所以我正在寻找更接近这个的东西:

var mySort = "title"
myArray.sorted(by: { $0.mySort < $1.mySort })

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

谢谢。

【问题讨论】:

标签: swift


【解决方案1】:

取决于您对 Objective-C 代码的容忍程度,答案范围从“不可能”(纯 Swift)到“不优雅”(带有 Objective-C 转换的 Swift),再到“只使用 Objective-C 类型”(即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 等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 2020-07-18
    • 2011-08-21
    • 1970-01-01
    • 2018-04-07
    相关资源
    最近更新 更多