用 tie 元素按值排序字典不应更改其顺序

Sort Dictionary by value with tie Element should not change their order

我有一个 [String: Int] 类型的字典,它的值为

let dic = [“a”:4, “b”:3, “c”:3]

我想按值和使用方法对字典进行排序

dic  = dic.sorted(by: { [=11=].value < .value })

结果

dic = [“c”:3, “b”:3, “a”:4]

它正在对字典进行排序,但我希望相同的值不应该排序或更改它们的顺序,例如,我想要这个结果

dic = [“b”:3, “c”:3, “a”:4]

字典无序。这意味着无论您在代码中看到 KVP 的顺序如何,都不能保证得到维护。 sort 调用仅表示按值排序,因此键可以按照他们想要的任何顺序排列。

另请注意 Swift 的 sorted(by:) 不是 stable。这意味着不能保证被认为是相等的东西保持它们的顺序。

因此,如果您坚持使用 Swift 的内置算法,您将无能为力。您可以自己编写一个插入排序(一种稳定的排序算法)并使用它。

另一个解决方案是按值排序 KVP,然后按键排序:

let newDict = dict.sorted(by: { [=10=].value == .value ? [=10=].key < .key : [=10=].value < .value })

显然,这仅在您的玩家名称最初按字典顺序排列时才有效。

或者,创建一个 Player 结构并使用 Player 数组:

struct Player {
    let name: String
    var score: Int
}

这里的主要问题是 dictionary is an unordered collection,因此试图对其进行排序并不是最好的做法。

如果您想存储游戏的得分值(即排行榜),您可以使用 tuples

typealias Score = (username: String, score: Int)

然后使用可以创建该元组的数组并按您想要的方式对它们进行排序。

var scores = [Score]()

// fill the scores
scores.append(("a", 4))
scores.append(("b", 3))
scores.append(("c", 3))

scores.sort {
    return [=11=].score < .score || ([=11=].score == .score && [=11=].username.localizedCaseInsensitiveCompare(.username) == .orderedAscending)
}