2014-11-30 29 views
6

Ich versuche, einen Unterschied von 1 Liste der Paare von einem anderen in Groovy Sprache zu bekommen. Paare sind nur (x, y) Koordinaten und sie sind einzigartig. Unten ist ein kleines Beispiel für die Einfachheit. Beachten Sie, dass Listen Dutzende von Paaren enthalten können.Groovy Sprache: wie man den Unterschied zwischen zwei Listen der Paare

def l1 = [[x:1, y:1]] 
    def l2 = [[x:0, y:0]] 
    println l1 - l2 

wird [] erhalten, dass eine leere Liste ist, sollte aber sein, dies: [[x: 1, y: 1]]

Update:

for(n in l2) { 
    l1 = l1 - n 
} 

Es funktioniert , aber es ist eine schwarze Magie und nicht

+0

Was meinst du mit Unterschied? Sie wollen, dass jedes x, y von l2 von demselben Index in l1 subtrahiert wird? Und du "arbeitest für mich" Beispiel dort mach die Dinge nur noch verwirrender, weil ich bezweifle, was du willst (halt einfach l1) – cfrick

+0

@cfrick Der Unterschied wie in Mathematik: wir subtrahieren l2 set von l1 set. Das Ergebnis ist = alles in l1, aber nicht in l2. Behandle (x, y) als ein Element, dh (x, y) in l1, aber nicht in l2. Hier ist ein gutes Beispiel: http://mrhaki.blogspot.ru/2010/08/groovy-goodness-subtracting-map-entries.html –

+0

ic. das [x: 0, y: 0] -Paar ist etwas seltsam. es funktioniert mit 'minus()', wenn einer von ihnen nicht "falsy" ist – cfrick

Antwort

6

in den Kommentaren, wie gesagt optimiert ist, sind die Paare in l1 einzigartig (oder besser gesagt: es ist in Ordnung einzigartige Ergebnisse haben), dann c Sie eine Verwendung l1/l2 als Sätze:

l1 = [[x:1, y:1]] 
l2 = [[x:0, y:0]] 
println l1.toSet()-l2.toSet() 
//; [[x:1, y:1]] 

Das Problem ursprünglich ist die [x:0,y:0] vs [x:1,y:1] Teil. Der Grund ist in public static <T> Collection<T> minus(Collection<T> self, Collection<?> removeMe). Die n * n branchs wird gewählt und das NumberAwareComperator denkt beide Karten sind gleich:

def cmp = new org.codehaus.groovy.runtime.NumberAwareComparator() 
println cmp.compare(l1[0], l2[0]) 
//; 0 (equal!) 

die einfach läuft darauf hinaus:

assert [x:1, y:1].hashCode() == [x:0, y:0].hashCode() 
    // 120^1 + 121^1 == 120^0 + 121^0 

bearbeiten Alternative (wenn Sie loswerden der Karte bekommen kann)

Da dies für eine Basis nicht so gut aussieht, ist es vielleicht besser, eine sichere und klanglich vergleichbare Klasse für Ihre Daten zu verwenden. z.B .:

@groovy.transform.Immutable 
class Pair { 
    long x,y 
} 

def p00 = new Pair(0,0) 
def p11 = new Pair(1,1) 
def p11o = new Pair(1,1) 

assert [p00]-[p11] == [p00] 
assert [p11]-[p00] == [p11] 
assert [p00].intersect([p11]) == [] 
assert [p11].intersect([p00]) == [] 
assert [p11].intersect([p11o]) == [p11] 
assert [p11].intersect([p11o]) == [p11o] 

Auch die Karten in Expando s Drehen besser funktioniert.

+0

BTW, [[x: 0, y: 0]]. ToSet(). Intersect ([[x: 1, y: 1]]). ToSet() funktioniert auch nicht und ich habe keine Problemumgehung . Höchstwahrscheinlich werde ich diese 0/0 überprüfen und getrennt damit umgehen müssen. –

+0

Und [x: 1, y: 1] .hashCode() == [x: 0, y: 0] .hashCode() lässt mich glauben, dass es ein Fehler in Groovy ist. Sie behandeln sie gleich, seltsam. –

+0

@vibneiro das ist Java-Code dort. Die Frage ist, tut NumberAwareComperator Shortcut ein wenig zu viel mit nur die hashCodes dort. im Grunde ist der Hashcode "120^1 + 121^1 == 120^0 + 121^0". Überall gibt es Zusammenstöße. – cfrick