如何在Swift中乘以字典中的每个值

时间:2016-02-06 20:08:35

标签: swift dictionary

所以,目前我有这本词典:

var data : [Int:Float] = [0:0,1:1,2:1.414,3:2.732,4:2,5:5.236,6:3.469,7:2.693,8:5.828,9:3.201]

我想创建一个新词典,比如说“newData”。我希望“newData”具有与“data”相同的键,但我想将“data”中的每个值乘以某个常量(比如“multiple”)以获取“newData”中的值。我怎么能这样做?

谢谢!

4 个答案:

答案 0 :(得分:2)

var newData = data

for (key, value) in newData
{
    newData[key] = value * multiple
}

答案 1 :(得分:2)

鉴于

let data : [Int:Float] = [0:0,1:1,2:1.414,3:2.732,4:2,5:5.236,6:3.469,7:2.693,8:5.828,9:3.201]
let factor: Float = 2

您可以使用reduce方法

let multiplied = data.reduce([Int:Float]()) { (var result, elm) -> [Int:Float] in
    result[elm.0] = elm.1 * factor
    return result
}

结果。

[3: 5.464, 2: 2.828, 4: 4.0, 9: 6.402, 5: 10.472, 6: 6.938, 7: 5.386, 0: 0.0, 8: 11.656, 1: 2.0]
  

请忽略订单,因为字典没有。

为什么这个解决方案比for循环更好?

我在这里建议的代码确实遵循功能编程范例。与经典for循环相比有几个优点:

  1. 它的线程安全:由于只使用了不可变值,因此您不必担心在使用它们时可能会更改这些值的其他线程。
  2. 它更快:在引擎盖下,结果的元素是并行处理的
  3. 它不易出错,因为它更具说明性:我们正在描述结果应该如何,而不是如何构建它。

答案 2 :(得分:1)

另一种基于map

的解决方案
let dict1 = ["a":1, "b":2, "c":3]
// Make a copy since we don't want to modify the original
var dict2 = dict1
let multiple = 5

dict2.map { (k,v) in dict2[k] = v*multiple }

我使用10000和100000元素阵列进行了一些简单的性能测试,提出的各种解决方案就像这样执行

  1. For循环:10000个元素1.28 ms,100000个元素12.28 ms
  2. 地图():10000个元素1.24毫秒,100000个元素12.23毫秒
  3. Reduce():10000个元素2.36 ms,100000个元素17.18 ms
  4. 但是你没有10000+元素阵列。值得注意的是差异。

答案 3 :(得分:0)

从Swift 4开始,Dictionary具有一个名为mapValues(_:)的属性。 mapValues(_:)具有以下声明:

  

返回一个新字典,其中包含该字典的键以及由给定的闭包转换的值。

func mapValues<T>(_ transform: (Value) throws -> T) rethrows -> Dictionary<Key, T>

下面的Swift 5 Playground示例代码显示了如何使用mapValues(_:)通过将现有字典的每个值相乘来创建新字典:

let multiple: Float = 2
let data: [Int : Float] = [0 : 0, 1 : 1, 2 : 1.4, 3 : 2.7, 4 : 2, 5 : 5.2]

let newData = data.mapValues { (value: Float) -> Float in
    return value * multiple
}
//let newData = data.mapValues { $0 * multiple } // also works

print(newData) // [3: 5.4, 4: 4.0, 2: 2.8, 0: 0.0, 1: 2.0, 5: 10.4]