【问题标题】:how do I sort an NSMutableSet in Swift?如何在 Swift 中对 NSMutableSet 进行排序?
【发布时间】:2020-03-07 22:30:39
【问题描述】:

我正在尝试使用 NSMutableOrderedSet 来存储一些数据,但我想按特定属性对集合进行排序。我试图在网上查看如何使用 NSMutableOrderedSet 的 sort(comarator cmptr: (Any, Any) -> ComparisonResult) 函数,但我不确定如何使用它。我想知道是否有人可以给我一个简单的例子,我在 Apple 开发者文档中找不到任何教程或示例。

目前我有:

jersey.swift:

    struct Jersey{
       var name: String
       var number: Int
}

viewcontroller.swift:

let firstBasemanJersey = Jersey(name: "Bob", number: 5)
let secondBasemanJersey = Jersey(name: "Jim", number: 15)
let thirdBasemanJersey = Jersey(name: "Jon", number: 1)
let catcherJersey = Jersey(name: "Steve", number: 79)

var jerseySet = NSMutableOrderedSet()
jerseySet.addObject(firstBasemanJersey)
jerseySet.addObject(secondBasemanJersey)
jerseySet.addObject(thirdBasemanJersey)
jerseySet.addObject(catcherJersey)

我想按 jersey.number 对集合进行排序,有人可以告诉我如何使用

self.something.sort { (<#Any#>, <#Any#>) -> ComparisonResult in
            <#code#>
        }

【问题讨论】:

  • 由于OrderedSet 使用Any 作为元素类型,因此在Swift 中使用它并不是一个好的结构。另请注意,您应该首先将Jersey 声明为Hashable,否则OrderedSetSet 部分将无法真正工作(即contains 方法将无法工作,您将能够多次插入同一个对象)。
  • @Sulthan 我完全同意这一点。我对提供答案持谨慎态度,但这样做只是为了帮助澄清 api 的使用。
  • @Alladinian OrderedSet 的真正用法是结合SetArray,其中所有操作都在两个子结构上自动执行。例如,如果Set 已包含该项目,则不会发生add。如果最终目的是对项目进行排序,则无需在更新时保持项目有序。我可能会创建自己的 Swift 通用结构,而不是 OrderedSet
  • @Sulthan 再次,完全同意......因此我回答的第二部分。话虽如此,我试图对 OP 的意图做出尽可能少的假设。如果这是针对在列表中添加唯一项目的 UI 并且有一个按钮可以让您按数字(例如)对它们进行排序(就地)怎么办?对于有序集和(可能的)排序,这将是一个有效的案例。我同意,如果我们获得有关此代码使用的更多详细信息,那么对此进行更深入的回答会更合适。

标签: ios swift nsmutableorderedset


【解决方案1】:

在最基本的形式中,您只需比较两个参数(一对 Any 对象,因为 Set 不“知道”当前持有什么对象)并返回一个 ComparisonResult 可以是 @ 987654323@、orderedDescendingorderedSame

jerseySet.sort(comparator: { lhs, rhs in
    guard let (l, r) = (lhs, rhs) as? (Jersey, Jersey) else { return .orderedSame }
    guard l.number != r.number else { return .orderedSame }
    return l.number < r.number  ? .orderedAscending : .orderedDescending
}) 

现在如果你print(jerseySet.array):

[Jerseys.Jersey(姓名:“Jon”,号码:1),Jerseys.Jersey(姓名:“Bob”,号码:5),Jerseys.Jersey(姓名:“Jim”,号码:15), Jerseys.Jersey(姓名:“史蒂夫”,号码:79)]

而且(由于问题 cmets 中提到的原因)这里是一个“更快捷”的版本:

struct Jersey: Hashable {
   let name: String
   let number: Int
}

let firstBasemanJersey  = Jersey(name: "Bob", number: 5)
let secondBasemanJersey = Jersey(name: "Jim", number: 15)
let thirdBasemanJersey  = Jersey(name: "Jon", number: 1)
let catcherJersey       = Jersey(name: "Steve", number: 79)

// Kept as var assuming that you will later `.insert` things in the set
var jerseySet = Set([
    firstBasemanJersey,
    secondBasemanJersey,
    thirdBasemanJersey,
    catcherJersey
])

let sortedByNumber = jerseySet.sorted { lhs, rhs in
    lhs.number < rhs.number
}

【讨论】:

    猜你喜欢
    • 2012-01-26
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    相关资源
    最近更新 更多