将变量传递到排序闭包的快速语法

标签 swift

我有一个 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 })

实现此功能的正确语法是什么?

谢谢。

最佳答案

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

关于将变量传递到排序闭包的快速语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49950513/

相关文章:

ios - 在 iOS 的 Google Maps SDK 中启用方向

ios - 仅在信息不存在时才将数据写入 firebase - Swift iOS

ios - 如何在 10 毫秒的时间间隔内将纬度和经度附加到字典数组中?

ios - 返回事件在 swift 3.0 中的哪里

javascript - 检查颜色是否接近

ios - 使用元组 Swift 3 在单个 switch-case 中实现多个间隔

swift - iOS 图表 : Determine Circle Position on chartValueSelected()

json - 如何将 NSArray 存储在 Userdefaults 中?

ios - 如何获取 UIButton ID?

macos - 如何对 Swift 结构使用 Cocoa 绑定(bind)