2016-12-21 1 views
1

У меня есть два LinkedHashMap с одним и тем же набором ключей. Я хочу выполнить точечный продукт между ними на основе ключей.Точный продукт HashMap в Groovy

Это, как я сейчас делаю это:

def dotProduct(a,b) { 
    acc = 0 
    a.keySet().each { acc += a[it] * b[it] } 
    acc 
} 

Есть ли понятнее/быстрый способ?

+1

Не требуется acc. 'return a.keySet(). collect {a [it] * b [it]} .sum()' –

+1

Я никогда не использовал Groovy, но вы можете попробовать либо 'a.collect {k, ak -> ak * b [k]} .sum() 'или' a.inject (0) {acc, k, ak -> acc + ak + b [k]} '. – Bubletan

+0

@AlinPandichi, вы хотите оставить свой комментарий в качестве ответа? Я приму это – gsmafra

ответ

1

Вам не нужно в соотв.

return a.keySet().collect { a[it] * b[it] }.sum() 
2

Вы можете иметь решение очень похоже на то, что вы делаете сейчас, используя inject (Groovy, 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() 

, скорее всего, яснее, если вы не совсем знакомы с функциональным молотком. Опасайтесь, чтобы этот массив создавал массив чисел перед суммированием всех значений.

Если вы используете 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() используется вместо Iterable.sum().

Смежные вопросы