Groovy: Difference with a.intersect( b ) and b.intersect( a ) Groovy: Difference with a.intersect( b ) and b.intersect( a ) arrays arrays

Groovy: Difference with a.intersect( b ) and b.intersect( a )


If you look at the source for Collection.intersect, you can see that the logic of the method follows this flow:

for two collections, left and right

  1. Swap left and right if left is smaller than right
  2. Add all of left into a Set (removes duplicates)
  3. For each element in right if it exists in the leftSet, then add it to the results

So, for your last 2 examples;

def array1 = ["hello", "world", "test", "test"]def array2 = ["world", "world", "world", "test"]

array1.intersect( array2 ) would give (if we wrote that same algorithm in Groovy):

leftSet = new TreeSet( array1 ) // both same size, so no swap// leftSet = [ 'hello', 'world', 'test' ]right   = array2result = right.findAll { e -> leftSet.contains( e ) }

Which (if you run it), you can see means result has the value [world, world, world, test] (as you found). This is because every element in right can be found in the leftSet

Not sure why the first example should return ["world","world"] though...

later...

So, what I think you are looking for would be something like this:

def array1 = ["hello", "world", "test", "test"]def array2 = ["world", "world", "world", "test"]def intersect1 = array1.intersect( array2 ) as TreeSetdef intersect2 = array2.intersect( array1 ) as TreeSetassert intersect1 == intersect2

in order that you cope with the duplicates in the collections, as then both intersect1 and intersect2 will be equal to

[test, world]

later still

I believe this does what you want:

[array1,array2]*.groupBy{it}.with { a, b -> assert a == b }