Сортировать словарь по значению с элементом связывания не следует менять их порядок
У меня есть словарь типа [String: Int] и его значение
let dic = [“a”:4, “b”:3, “c”:3]
Я хочу отсортировать словарь по значению и используя метод
dic = dic.sorted(by: { $0.value < $1.value })
Результат
dic = [“c”:3, “b”:3, “a”:4]
Это сортировка по словарю, но я хочу, чтобы значения, которые были одинаковыми, не сортировались и не меняли порядок, например, я хочу получить такой результат
dic = [“b”:3, “c”:3, “a”:4]
2 ответа
Основная проблема здесь в том, что словарь - это неупорядоченная коллекция, поэтому пытаться сортировать его - не лучшая вещь.
Если вы хотите сохранить значения для вашей игры (например, для таблицы лидеров), вы можете использовать кортежи.
typealias Score = (username: String, score: Int)
Затем use может создать массив этих кортежей и отсортировать их по своему усмотрению.
var scores = [Score]()
// fill the scores
scores.append(("a", 4))
scores.append(("b", 3))
scores.append(("c", 3))
scores.sort {
return $0.score < $1.score || ($0.score == $1.score && $0.username.localizedCaseInsensitiveCompare($1.username) == .orderedAscending)
}
Словарь неупорядочен. Это означает, что независимо от того, какой порядок вы видите в коде, KVP не гарантируется. sort
call только говорит, что сортирует по значениям, поэтому ключи могут быть в любом порядке, который они хотят.
Также обратите внимание, что Свифт sorted(by:)
не является стабильным Это означает, что вещи, которые считаются равными, не гарантируют сохранение своего порядка.
Следовательно, вы ничего не можете с этим поделать, если будете настаивать на использовании встроенных алгоритмов Swift. Вы можете написать сортировку вставкой (алгоритм стабильной сортировки) и использовать ее.
Другое решение - упорядочить KVP по значениям, а затем по ключам:
let newDict = dict.sorted(by: { $0.value == $1.value ? $0.key < $1.key : $0.value < $1.value })
Очевидно, это будет работать только в том случае, если имена ваших игроков изначально упорядочены лексикографически.
Или создайте Player
структурировать и использовать массив Player
s:
struct Player {
let name: String
var score: Int
}