Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do sane "set-difference" in Ruby?

Tags:

Demo (I expect result [3]):

[1,2] - [1,2,3] => []    # Hmm [1,2,3] - [1,2] => [3]   # I see  a = [1,2].to_set   => #<Set: {1, 2}> b = [1,2,3].to_set => #<Set: {1, 2, 3}> a - b              => #<Set: {}>  WTF! 

And:

[1,2,9] - [1,2,3] => [9]  # Hmm. Would like [[9],[3]] 

How is one to perform a real set difference regardless of order of the inputs?

Ps. As an aside, I need to do this for two 2000-element arrays. Usually, array #1 will have fewer elements than array #2, but this is not guaranteed.

like image 958
Zabba Avatar asked Jun 28 '12 04:06

Zabba


People also ask

How do I remove a specific element from an array in Ruby?

Array#delete() : delete() is a Array class method which returns the array after deleting the mentioned elements. It can also delete a particular element in the array. Syntax: Array. delete() Parameter: obj - specific element to delete Return: last deleted values from the array.

How do you clean an array from items matching a condition in Ruby?

Using delete_if# method The delete_if method accepts a conditional and removes all the elements in the array that do not meet the specified condition. The method takes a block and evaluates each element for a matching case. If the value does not meet the set conditions, the method removes it.

How do you pop an array element in Ruby?

The pop() function in Ruby is used to pop or remove the last element of the given array and returns the removed elements. Parameters: Elements : This is the number of elements which are to be removed from the end of the given array.


1 Answers

The - operator applied to two arrays a and b gives the relative complement of b in a (items that are in a but not in b).

What you are looking for is the symmetric difference of two sets (the union of both relative complements between the two). This will do the trick:

a = [1, 2, 9] b = [1, 2, 3] a - b | b - a          # => [3, 9] 

If you are operating on Set objects, you may use the overloaded ^ operator:

c = Set[1, 2, 9] d = Set[1, 2, 3] c ^ d                  # => #<Set: {3, 9}> 

For extra fun, you could also find the relative complement of the intersection in the union of the two sets:

( a | b ) - ( a & b )  # => #<Set: {3, 9}> 
like image 91
Jon Gauthier Avatar answered Sep 18 '22 19:09

Jon Gauthier