通过从另一个数组排序来对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"]
我将要做的:
- 创建一个以位置为键的字典,以及该位置的玩家数组作为值。 O(n),其中n是玩家的数量。
- 循环通过你的
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 加载对数据进行排序