【问题标题】:Sort array by order of values in other array [duplicate]按其他数组中值的顺序对数组进行排序[重复]
【发布时间】:2017-05-17 06:25:13
【问题描述】:

我有一个定义订单的数组,

let orderSettingArray = ["Admiral", "Captain", "Lieutenant"]

还有另一个包含这些值的数组

var myArray = ["Lieutenant", "Captain"]

我想对myArray进行排序以反映orderSettingArray的顺序:

var myArraySorted = myArray.getSorted(by: orderSettingArray)

现在print(myArraySorted) 应该打印["Captain", "Lieutenant"]

【问题讨论】:

  • 军衔是枚举的理想用例之一。您应该利用这一点。
  • @NiravD:你是对的(我应该知道那个:) - 这个问题有点笼统,因为它要求使用数组扩展方法,但基本思想是相同的.让我们等待更多意见是否将其作为副本关闭。
  • @MartinR 我知道这就是为什么我添加重复问题作为建议
  • 军衔只是一个例子。真实场景具有可自定义的字符串。 @亚历山大

标签: arrays swift sorting


【解决方案1】:

这么简单let new = orderSettingArray.filter{ return myArray.contains($0) }

【讨论】:

    【解决方案2】:
    • 将每个数组元素映射到一个(element, index) 元组,其中 index 是 order 数组中数组元素的索引。 在你的例子中,这将是

      [("Lieutenant", 2), ("Captain", 1)]
      
    • 按第二个元组元素(索引)对元组数组进行排序。 你的情况

      [("Captain", 1), ("Lieutenant", 2)]
      
    • 从已排序的元组数组中提取数组元素。 你的情况

      ["Captain", "Lieutenant"]
      

    代码(适用于任何相等元素的数组,不限于字符串数组):

    extension Array where Element: Equatable {
        func getSorted(by orderArray: [Element]) -> [Element] {
    
            return self.map { ($0, orderArray.index(of: $0) ?? Int.max) }
                .sorted(by: { $0.1 < $1.1 })
                .map { $0.0 }
    
        }
    }
    
    let orderSettingArray = ["Admiral", "Captain", "Lieutenant"]
    let myArray = ["Lieutenant", "Captain"]
    let myArraySorted = myArray.getSorted(by: orderSettingArray)
    print(myArraySorted) // ["Captain", "Lieutenant"]
    

    myArray 中不存在于orderSettingArray 中的元素 被分配了索引Int.max,因此排序到最后 结果。

    【讨论】:

    • 你好,你不觉得this answer更简单吗?它应该适用于任何可等价元素的数组,不限于字符串数组...
    • @AhmadF:不同之处在于它不会处理myArray 中的重复元素,或者myArray 中不在orderSettingArray 中的元素。如果这不是问题,则解决方案很好。
    【解决方案3】:

    更新

    我为此找到了更好的设计。它有很多改进:

    • 我使用Dictionary 来加快订购查找速度
    • 通过将此行为提取到单独的类型中,字典可以被缓存并在多个排序之间重用
    • 排序派生与排序分离,因此可以以更多方式使用
    • omitEntirely 职责已完全删除。它应该通过简单地调用filter 来完成,hardcodedOrdering.contains 作为谓词。

    See my new answer, here

    【讨论】:

    • 哇,如此详尽的答案。
    • @JOG 是的,这是我不得不多次执行的操作,所以我花了很多时间来构建和完善它
    【解决方案4】:

    斯威夫特 3

    extension Array where Element: Hashable {
        func getSorted(by: Array<String>) -> Array<String> {
            var d = Dictionary<Int, String>()
    
            for value in self {
                for i in 0 ..< by.count {
                    if value as! String == by[i] {
                        d[i] = value as? String
                    }
                }
            }
    
            var sortedValues = Array<String>()
            for key in d.keys.sorted(by: <) {
                sortedValues.append(d[key]!)
            }
    
            return sortedValues
        }
    }
    

    【讨论】:

    • 请注意,这仅适用于[String]
    • 天哪,这太复杂了。
    • 不是最优的,当然。复杂,不。 :)
    猜你喜欢
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2013-07-26
    • 2014-05-14
    • 2012-10-24
    • 2012-05-16
    • 2013-11-02
    相关资源
    最近更新 更多