通过从另一个数组排序来对Swift数组进行排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过从另一个数组排序来对Swift数组进行排序相关的知识,希望对你有一定的参考价值。

假设我有一个自定义类[Player]的数组,每个包含一个名为player.position的字符串属性

我也有一个任意数组的值,称为positionOrders,如下所示:

let positionOrders = ["QB", "WR", "RB", "TE"]

我的目标是将[Player]排序为首先拥有所有“QB”,然后是“WR”,“RB”,最后是“TE”。

我正在做的当前方式循环遍历positionOrders中的每个元素,然后在内部循环遍历所有玩家以附加到新阵列。但是,我无法想出一种更简单(更有效)的方法。非常感谢任何提示或指示。谢谢。

答案

对于小尺寸的positionOrders,这是一种可行的方法:

let sorted = players.sorted{ positionOrders.index(of: $0.position)! < positionOrders.index(of: $1.position)! }

这是一个更复杂的解决方案,对于更大尺寸的positionOrders来说会更快

let ordering = Dictionary(uniqueKeysWithValues: x.enumerated().map { ($1, $0) })

let sorted = players.sorted{ ordering[$0.position]! < ordering[$1.position]! }

这两种解决方案都假设所有可能的玩家位置都根据positionOrders有一个定义的顺序,因此他们使用!来简洁。如果不是这样,请告诉我。

另一答案

基于亚历山大的答案,我实施了一个扩展来做到这一点。

extension Array where Element == String {

func reordered() -> [String] {

    let defaultOrder = ["orange", "pear", "watermelon", "grapefruit", "apple", "lemon", "tomatoes"]

    return self.sorted { (a, b) -> Bool in
        if let first = defaultOrder.index(of: a), let second = defaultOrder.index(of: b) {
            return first < second
        }
        return false
    }
}

let arrayToSort = ["lemon", "watermelon", "tomatoes"]
let sortedArray = arrayToSort.reordered()
print(sortedArray) // ["watermelon", "lemon", "tomatoes"]
另一答案

这是一个基于OuSS代码的通用Swift 4解决方案,需要数组元素为Equatable。

extension Array where Element: Equatable {

    func reorder(by preferredOrder: [Element]) -> [Element] {

        return self.sorted { (a, b) -> Bool in
            guard let first = preferredOrder.index(of: a) else {
                return false
            }

            guard let second = preferredOrder.index(of: b) else {
                return true
            }

            return first < second
        }
    }
}

let currentPositions = ["RB", "AA", "BB", "CC", "WR", "TE"]
let preferredOrder = ["QB", "WR", "RB", "TE"]
let sorted = currentPositions.reorder(by: preferredOrder)
print(sorted) // ["WR", "RB", "TE", "AA", "BB", "CC"]
另一答案

我将要做的:

  1. 创建一个以位置为键的字典,以及该位置的玩家数组作为值。 O(n),其中n是玩家的数量。
  2. 循环通过你的positionOrders并获取值到每个键(位置)。

这是代码:

    let preSortPlayerList = [Player]() // Filled with your players.
    let positionOrders = ["QB", "WR", "RB", "TE"]
    let dict = preSortPlayerList.reduce([String : [Player]]()) {
        var map = $0
        if var tmp = map[$1.position] {
            tmp.append($1)
            map[$1.position] = tmp
        } else {
            map[$1.position] = [$1]
        }
        return map
    }

    let playersArray: [Player] = positionOrders.flatMap { dict[$0] ?? [Player]() }
    print("\(playersArray)")
另一答案

对于迅捷4

非常简单的方式和勤奋(随意​​建议和纠正我)

func reOrder(array : [String] , order : [String]) -> [String]{ 

    //common elments in order
    // order.filter{array.contains($0)}

    // the rest of the array that the order doesnt specify
    // array.filter{!order.contains($0)}

 return order.filter{array.contains($0)} + array.filter{!order.contains($0)}
}


let list =     ["A", "Z", "B", "H", "C", "T", "D", "E"] 
let newOrder = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]




print("The ordered list is ",reOrder(array: list, order: newOrder))


 // The ordered list is  ["A", "B", "C", "D", "E", "H", "Z", "T"]

如果有人可以将它作为Generic类型的扩展,那将是一件好事,我对此并不擅长

另一答案

基于Emily代码,我对扩展做了一些更改,因为它不会使defaultOrder中不存在的元素结束

extension Array where Element == String {

func reordered() -> [String] {

    let defaultOrder = ["lemon", "watermelon", "tomatoes"]

    return self.sorted { (a, b) -> Bool in
        guard let first = defaultOrder.index(of: a) else {
            return false
        }

        guard let second = defaultOrder.index(of: b) else {
            return true
        }

        return first < second
    }
}

let arrayToSort = ["orange", "watermelon", "grapefruit", "lemon", "tomatoes"]
let sortedArray = arrayToSort.reordered()
print(sortedArray) // ["watermelon", "lemon", "tomatoes", "orange", "grapefruit"]

以上是关于通过从另一个数组排序来对Swift数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章

编写一个函数对对象数组进行排序(通过使用另一个对象来指定排序路径和顺序)

为啥我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序?

按另一个数组排序数组?

HandsonTable 通过从 ajax 加载对数据进行排序

根据存在于另一个模型数组中的日期对模型数组进行排序。斯威夫特 3

使用日期 Swift 3 对字典数组进行排序