Swift 字典中元素的加权平均
我有一本这样的字典:Swift 字典中元素的加权平均,swift,swift4,Swift,Swift4,我有一本这样的字典: let tempDict = [100:2, 101:3, 102:4] 我需要找到字典中所有元素的加权平均值。所以我基本上想这样做 let keyMultValues = 100*2+101*3+102*4 let valTotal = 2+3+4 let final = keyMultValues/valTotal 我知道我可以循环浏览字典中的所有条目,但我想也许有一种更有效、更干净的方法来做到这一点 还有比这更好的方法吗 var keyMultValues = 0
let tempDict = [100:2, 101:3, 102:4]
我需要找到字典中所有元素的加权平均值。所以我基本上想这样做
let keyMultValues = 100*2+101*3+102*4
let valTotal = 2+3+4
let final = keyMultValues/valTotal
我知道我可以循环浏览字典中的所有条目,但我想也许有一种更有效、更干净的方法来做到这一点
还有比这更好的方法吗
var keyMultValues = 0.0
tempDict.forEach({
keyMultValues += $0.key*$0.value
})
let valTotal = reduce(priceDict.values, 0, +) //this part isn't working properly so any help you can give here would be great. I am using swift 4
这个怎么样
let keyValueProductsSum = dict.lazy.map(*).reduce(0, +)
let valueSum = dict.values.reduce(0, +)
let weightedAverage = keyValueProductsSum / valueSum
两项意见:
let dictionary = [100:2, 101:3, 102:4]
这也适用于较大的值,例如:
let dictionary = [
1_000_000_000: 20_000_000_000,
1_000_000_001: 30_000_000_000,
1_000_000_002: 40_000_000_000
]
您从以下内容开始:
var keyMultValues = 0
tempDict.forEach({
keyMultValues += $0.key*$0.value
})
let valTotal = reduce(priceDict.values, 0, +) //this part isn't working properly so any help you can give here would be great. I am using swift 4
并询问:
还有比这更好的方法吗
var keyMultValues = 0.0
tempDict.forEach({
keyMultValues += $0.key*$0.value
})
let valTotal = reduce(priceDict.values, 0, +) //this part isn't working properly so any help you can give here would be great. I am using swift 4
你的错误是你写的reduce
不正确,应该是:
tempDict.values.reduce(0, +)
使用此修复程序,您的代码将生成正确的(使用整数算术)结果
但是,您的代码对数据进行了两次传递,foreach
和reduce
(编写本文时的其他答案进行两次或三次)。您自己的解决方案显示,您只需进行一次传递,只需修改它,使其遵循与用于keymultvalue
相同的valTotal
模式:
var keyMultValues = 0
var valTotal = 0
tempDict.forEach({
let val = $0.value // we are going to use it twice
keyMultValues += $0.key * val
valTotal += val
})
let final = keyMultValues / valTotal
这只需对数据进行一次传递
如果您的数字很大,您可能需要使用“边走边除算法”进行两次传递,如果您希望找到浮点加权平均值,则需要加入一些Double
cast。@Rob的答案涵盖了这两个方面
一次传递数据是否真的比两次更好(更快、更少的内存等等)?这只是一个练习!我添加此答案只是为了向您展示您最初的尝试离正确的解决方案有多近。让我看看。只是出于好奇,懒惰是为了什么?它的作用是什么?@NevinJethmalani它延迟了数组的生成,以包含
map
的结果。因为我们只需要迭代这些值,然后用.reduce(0,+)
求和,所以没有理由让map
浪费时间分配一个新的数组,并将所有结果复制到其中,只有我们在迭代数组一次后才能丢弃它。因此,如果我们去掉懒惰的数组,它是否仍会以同样的方式工作,但这只是一种更糟糕的方式?您可以简化映射,只需通过操作符map(*)
@LeoDabus哦,是的reduce(priceDict.values,0,+)
是Swift 1语法。在Swift 2中,一大堆无组织的自由函数被移动到Sequence等人的实例方法中!谢谢字典中只有几个值,所以我们不需要担心这些问题。但我会调查的!