用 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)
}
我有一个 [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)
}