2016-12-21 3 views
1

Ich habe zwei LinkedHashMap s mit dem gleichen Satz von Schlüsseln. Ich möchte das Skalarprodukt zwischen ihnen basierend auf Schlüsseln ausführen. DiesePunkt Produkt von HashMap in Groovy

ist, wie ich es derzeit tue:

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

Gibt es einen klareren/schnelleren Weg?

+1

Sie brauchen nicht acc. 'return a.keySet(). collect {a [it] * b [it]} .sum()' –

+1

Ich habe Groovy noch nie benutzt, aber Sie könnten versuchen entweder 'a.collect {k, ak -> ak * b [k]} .sum() 'oder' a.inject (0) {acc, k, ak -> acc + ak + b [k]} '. – Bubletan

+0

@AlinPandichi, möchtest du deinen Kommentar als Antwort posten? Ich werde es akzeptieren – gsmafra

Antwort

1

Sie brauchen nicht acc.

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

Sie eine Lösung sehr ähnlich haben können, was Sie jetzt tun inject (Groovy functional fold) nutzen, so dass:

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] } 

Wie auch immer, -Lösung Alin Pandichi

assert 28 == a.keySet().collect({ a[it] * b[it] }).sum() 

ist wahrscheinlich klarer, wenn Sie mit funktionellem Groovy nicht vertraut sind. Beachten Sie, dass dieser eine Reihe von Zahlen erzeugt, bevor alle Werte summiert werden.

Wenn Sie mit Java 8 und Groovy> 2.3 können Sie Java 8 Streams API nutzen und einen Groovy-Verschluss als Java Lambda verwenden:

assert 28 == a.entrySet().stream().mapToInt({ it.value * b[it.key] }).sum() 

wo IntStream.sum() statt Iterable.sum() verwendet wird.