2017-03-27 36 views
1

说我有自定义类[Player]的阵列,其中每个都包含称为player.position排序一个夫特阵列通过从另一阵列订货

我也有值任意阵列的串属性,称为positionOrders,像这样:

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

在哪里我的目标是到[Player]排序有所有的 “QB” 第一个,然后在 “WR” S “RB”,且最终 “TE” S。

我正在做的循环方式是通过positionOrders中的每个元素,然后在循环中通过所有玩家追加到一个新数组。但是,我无法想出一个更简单(更有效)的方法来做到这一点。任何提示或指针非常感谢。谢谢。

+0

存在给我们一些输入数据一起玩的元素。 – Alexander

+0

将订单转换为枚举或其他类型。定义它可比较。使用该比较来分类玩家。 – Sulthan

+0

数组'positionOrders'常量还是在运行时更改? – Sulthan

回答

7

对于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,所有可能的玩家位置都有一个明确的排序,因此为简洁起见,他们使用!。如果情况并非如此,请告诉我。

+0

当然这段代码需要安全地查看索引结果,因为位置不在positionOrders数组中。 – rmaddy

+0

而你需要$ 0。位置“和”$ 1.position“。 – rmaddy

+0

@rmaddy好点,固定 – Alexander

1

我会做什么:

  1. 与地位的关键,而玩家在该位置作为值的Array创建一个字典。 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)") 
+0

你可以使用flatmap来创建'playersArray' – Alexander

+0

@Alexander,其实你是对的。刚更新了答案。谢谢。 – antonio081014

1

,我实现了一个扩展做到这一点。

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"] 
0

基于艾米丽代码,我做了一些改变,以扩展事业也不会做出不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"]