您可以先将具有相同分数的团队分组到字典中,从而简化它。然后对字典进行排序(根据分数递减),枚举它(得到偏移量)并构建排名列表:
let dict:[String:Int] = ["team1":79, "team2":5, "team3":18, "team4":5, "team5": 82, "team6": 1]
let ranking = Dictionary(grouping: dict, by: { $0.value })
.sorted(by: { $0.key > $1.key })
.enumerated()
.flatMap { (offset, elem) in
elem.value.map { (team: $0.key, rank: offset + 1 )}
}
print(ranking)
// [(team: "team5", rank: 1), (team: "team1", rank: 2),
// (team: "team3", rank: 3), (team: "team2", rank: 4),
// (team: "team4", rank: 4), (team: "team6", rank: 5)]]
详细解释:
Dictionary(grouping: dict, by: { $0.value })
创建一个字典,其键是球队得分,其值是具有该分数的球队的数组。
.sorted(by: { $0.key > $1.key })
通过递减键对字典进行排序,结果是一个元组数组:
[(key: 82, value: [(key: "team5", value: 82)]),
(key: 79, value: [(key: "team1", value: 79)]),
(key: 18, value: [(key: "team3", value: 18)]),
(key: 5, value: [(key: "team2", value: 5), (key: "team4", value: 5)]),
(key: 1, value: [(key: "team6", value: 1)])]
然后
.enumerated()
从此数组创建一个惰性序列(偏移量,元素)对:
(offset: 0, element: (key: 82, value: [(key: "team5", value: 82)])),
(offset: 1, element: (key: 79, value: [(key: "team1", value: 79)])),
(offset: 2, element: (key: 18, value: [(key: "team3", value: 18)])),
(offset: 3, element: (key: 5, value: [(key: "team2", value: 5), (key: "team4", value: 5)])),
(offset: 4, element: (key: 1, value: [(key: "team6", value: 1)]))
最后flatMap 调用每个 (offset, element) 对的闭包并连接结果。在封闭内部,
elem.value.map { (team: $0.key, rank: offset + 1 )}
映射一个 (offset, element) 对和一个 (team, rank) 元组数组。例如,
(offset: 3, element: (key: 5, value: [(key: "team2", value: 5), (key: "team4", value: 5)]))
映射到
[(team: "team2", rank: 4), (team: "team4", rank: 4)]
flatMap() 连接这些数组,得到最终的ranking 数组。
这是最初发布的解决方案,它为示例数据生成排名 1、2、3、4、4、6(而不是 1、2、3、4、4、5):
let dict:[String:Int] = ["team1":79, "team2":5, "team3":18, "team4":5, "team5": 82, "team6": 1]
var ranking = [(team:String,rank:Int)]()
for (_, list) in Dictionary(grouping: dict, by: { $0.value })
.sorted(by: { $0.key > $1.key }) {
let pos = ranking.count + 1
ranking.append(contentsOf: list.map { ($0.key, pos )})
}
print(ranking)
// [(team: "team5", rank: 1), (team: "team1", rank: 2),
// (team: "team3", rank: 3), (team: "team4", rank: 4),
// (team: "team2", rank: 4), (team: "team6", rank: 6)]