Сортировать словарь по значению с галстуком Элемент не должен менять их порядок - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть словарь типа [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 ]

0 голосов
/ 07 сентября 2018

Основная проблема в том, что словарь представляет собой неупорядоченную коллекцию , поэтому пытаться сортировать его - не лучшая вещь.

Если вы хотите сохранить значения для вашей игры (например, для таблицы лидеров), вы можете использовать кортежи .

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)
}
0 голосов
/ 07 сентября 2018

Словарь неупорядочен. Это означает, что независимо от того, какой порядок вы видите в коде, KVP не гарантируется. Вызов sort говорит только о сортировке по значениям, поэтому ключи могут быть в любом порядке.

Также обратите внимание, что Swift's 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
}
...