ranking list
👉 replit
// name and score
let dict = [ // Dictionary<Key, Value>
"Sam": 79, "Joe": 5, "Mary": 79, // Key = String
"Tom": 5, "Alex": 82, "Nancy": 1 // Value = Int
]
// ⭐️ 1. sort it by value first
let sorted = dict.sorted { $0.value > $1.value }
var prev: Int? // previous score
var currentRank = 0
var rankingList = [(name: String, score: Int, rank: Int)]()
// ⭐️ 2. give every element a rank
for (i, elem) in sorted.enumerated() {
// if elem.value is not the same as previous score,
// update previous score and current rank
if prev == nil || elem.value != prev! {
prev = elem.value
currentRank = i + 1 // i is zero-based, rank is one-based
}
rankingList.append((elem.key, elem.value, currentRank))
}
print(rankingList)
/*
[
(name: "Alex" , score: 82, rank: 1),
(name: "Sam" , score: 79, rank: 2),
(name: "Mary" , score: 79, rank: 2), // no 3rd place
(name: "Joe" , score: 5, rank: 4),
(name: "Tom" , score: 5, rank: 4), // no 5th place
(name: "Nancy", score: 1, rank: 6)
]
*/
👉 paiza.io
let dict = [ // Dictionary<Key, Value>
"Sam": 79, "Joe": 5, "Mary": 18, // Key = String
"Tom": 5, "Alex": 82, "Nancy": 1 // Value = Int
] // Element = (key: Key, value: Value)
// ⭐️ 按照「分數」分組
let dict2 = dict.grouped { $0.value } // seq.grouped(by:) -> 👥 相關
/*
⭐️ seq.grouped(by:)
--------------------------------------
Sequence -> Dictionary<Key, [Element]>
其中 Key 為參數 by: (Element) -> Key 所指定。
[ Key ╭─── Value = [Element] ───╮
79: [(key: "Sam" , value: 79)],
5: [(key: "Tom" , value: 5) , (key: "Joe", value: 5)],
82: [(key: "Alex" , value: 82)],
18: [(key: "Mary" , value: 18)],
1: [(key: "Nancy", value: 1)]
]
*/
// ⭐️ 按照「分數」由大到小排列
let sorted = dict2.sorted { $0.key > $1.key }
/*
⭐️ seq.sorted(by:)
---------------------
Sequence -> [Element]
一個 Dictionary 的 Element = (key: Key, value: Value),
但現在的 Key = Int,Value = [(key: String, value: Int)],
所以經過 .sorted(by:) 之後自然會變成:
[(key: Int, value: [(key: String, value: Int)])]
[
(key: 82, value: [(key: "Alex" , value: 82)]),
(key: 79, value: [(key: "Sam" , value: 79)]),
(key: 18, value: [(key: "Mary" , value: 18)]),
(key: 5, value: [(key: "Tom" , value: 5), (key: "Joe", value: 5)]),
(key: 1, value: [(key: "Nancy", value: 1)])
]
*/
// ⭐️ 幫 Sequence 編號
let enumerated = sorted.enumerated()
/*
⭐️ seq.enumerated()
------------------------------------------
Sequence -> EnumeratedSequence<[Element]>
幫 Sequence 編號,編號後可用下列語法來處理每個元素:
for (i, elem) in seq.enumerated() { ... }
所以在本例中,可以假想成經過 .enumerated() 處理後,變成這樣:
[
(0, (key: 82, value: [(key: "Alex" , value: 82)])),
(1, (key: 79, value: [(key: "Sam" , value: 79)])),
(2, (key: 18, value: [(key: "Mary" , value: 18)])),
(3, (key: 5, value: [(key: "Tom" , value: 5), (key: "Joe", value: 5)])),
(4, (key: 1, value: [(key: "Nancy", value: 1)]))
]
*/
// ⭐️ 將 elem 元素內部的值(elem.value)轉變為陣列,然後在用 .flatMap()
// 將所有陣列「壓成」一維陣列。
let ranking = enumerated.flatMap { (i, elem) in
elem.value.map { (name: $0.key, rank: i + 1, value: $0.value) }
}
/*
[
(name: "Alex" , rank: 1, value: 82),
(name: "Sam" , rank: 2, value: 79),
(name: "Mary" , rank: 3, value: 18),
(name: "Tom" , rank: 4, value: 5),
(name: "Joe" , rank: 4, value: 5),
(name: "Nancy", rank: 5, value: 1)
]
*/
Swift ranking dictionary - build ranking list from scores
Last updated