Groovy 中 HashMap 的点积
Dot product of HashMap in Groovy
我有两个 LinkedHashMap 具有相同的键组。我想根据键在它们之间执行点积。
我目前是这样做的:
def dotProduct(a,b) {
acc = 0
a.keySet().each { acc += a[it] * b[it] }
acc
}
有clearer/faster方法吗?
您可以利用 inject (Groovy's functional fold) 获得与您现在正在做的非常相似的解决方案,因此:
def a = [1:1, 2:2, 3:3]
def b = [1:2, 2:4, 3:6]
assert (1*2 + 2*4 + 3*6) == a.inject(0) { result, k, v -> result += v * b[k] }
无论如何,Alin Pandichi 的 解决方案
assert 28 == a.keySet().collect({ a[it] * b[it] }).sum()
如果您不太熟悉函数 groovy, 可能会更清楚。请注意,这会在对所有值求和之前创建一个数字数组。
如果您使用 Java 8 和 Groovy > 2.3,您可以利用 Java 8 Streams API 并使用 Groovy 闭包作为 Java 拉姆达:
assert 28 == a.entrySet().stream().mapToInt({ it.value * b[it.key] }).sum()
其中 IntStream.sum()
is used instead of Iterable.sum()
.
你不需要acc。
return a.keySet().collect { a[it] * b[it] }.sum()
我有两个 LinkedHashMap 具有相同的键组。我想根据键在它们之间执行点积。
我目前是这样做的:
def dotProduct(a,b) {
acc = 0
a.keySet().each { acc += a[it] * b[it] }
acc
}
有clearer/faster方法吗?
您可以利用 inject (Groovy's functional fold) 获得与您现在正在做的非常相似的解决方案,因此:
def a = [1:1, 2:2, 3:3]
def b = [1:2, 2:4, 3:6]
assert (1*2 + 2*4 + 3*6) == a.inject(0) { result, k, v -> result += v * b[k] }
无论如何,Alin Pandichi 的 解决方案
assert 28 == a.keySet().collect({ a[it] * b[it] }).sum()
如果您不太熟悉函数 groovy,可能会更清楚。请注意,这会在对所有值求和之前创建一个数字数组。
如果您使用 Java 8 和 Groovy > 2.3,您可以利用 Java 8 Streams API 并使用 Groovy 闭包作为 Java 拉姆达:
assert 28 == a.entrySet().stream().mapToInt({ it.value * b[it.key] }).sum()
其中 IntStream.sum()
is used instead of Iterable.sum()
.
你不需要acc。
return a.keySet().collect { a[it] * b[it] }.sum()