首页 > 解决方案 > 通过在数组上减少创建字典与在迭代中分配每个项目之间的区别

问题描述

我在 StackOverflow 上遇到了一个问题:Swift - Convert Array to Dictionary ,用户想要获取数组的元素并希望将它们放入字典中并为每个元素分配 0。(作为玩家的关键和作为他们的分数的价值)所以:

var playerNames = ["Harry", "Ron", "Hermione"]

变成

var scoreBoard: [String:Int] = [ "Ron":0, "Harry":0, "Hermione":0 ]

这个问题有 2 个答案:1)在数组上使用 reduce

let scoreboard = playerNames.reduce(into: [String: Int]()) { $0[$1] = 0 }

2)创建一个字典并迭代数组以将每个值键对添加到其中

var dictionary = [String: Int]()
for player in playerNames {
    dictionary[player] = 0
}

我从https://github.com/nyisztor/swift-algorithms获取 BenchTimer 函数来测试这两种解决方法。而且它们似乎都在 O(n) 中运行。

在此处输入图像描述

在此处输入图像描述

我想知道为什么我们更喜欢第一个而不是另一个,因为编写第二个解决方案的人对他们的编码技能有一个不好的评价。

编辑:Apple 在较新版本中弃用了某些功能,所以坚持基础知识并创建我们自己的做事方式不是更好吗?

谢谢你的回答

标签: arraysswiftdictionarybig-ocode-cleanup

解决方案


今天,IMO,你不应该使用其中任何一个。我们现在拥有Dictionary.init(uniqueKeysWithValues:)并且.init(_:uniquingKeysWith:)哪个更清楚地说明了他们的意图,并使诸如重复键之类的极端情况变得明确。

如果您可以静态地证明所有键都是唯一的,那么您将使用第一个:

let scoreboard = Dictionary(uniqueKeysWithValues: playerNames.map { (name: $0, score: 0) })

如果您无法证明密钥是唯一的,则可以使用第二个,这样您就可以明确决定在发生冲突时该怎么做。

let scoreboard = Dictionary(playerNames.map { (name: $0, score: 0) },
                            uniquingKeysWith: { first, _ in first })

请注意这种方法如何允许标签明确键是什么以及值是什么。我没有对这段代码进行基准测试,但我希望它在时间方面与其他代码非常相似。


推荐阅读