Subtracting one Array from another in Ruby

Solution 1:

You can subtract arrays in Ruby:

[1,2,3,4,5] - [1,3,4]  #=> [2,5]

ary - other_ary → new_ary Array Difference

Returns a new array that is a copy of the original array, removing any items that also appear in other_ary. The order is preserved from the original array.

It compares elements using their hash and eql? methods for efficiency.

[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]

If you need set-like behavior, see the library class Set.

See the Array documentation.

Solution 2:

The above solution

a - b

deletes all instances of elements in array b from array a.

[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ]  #=>  [ 3, 3, 5 ]

In some cases, you want the result to be [1, 2, 3, 3, 5]. That is, you don't want to delete all duplicates, but only the elements individually.

You could achieve this by

class Array
  def delete_elements_in(ary)
    ary.each do |x|
      if index = index(x)
        delete_at(index)
      end
    end
  end
end

test

irb(main):198:0> a = [ 1, 1, 2, 2, 3, 3, 4, 5 ]
=> [1, 1, 2, 2, 3, 3, 4, 5]
irb(main):199:0> b = [ 1, 2, 4 ]
=> [1, 2, 4]
irb(main):200:0> a.delete_elements_in(b)
=> [1, 2, 4]
irb(main):201:0> a
=> [1, 2, 3, 3, 5]

The code works even when the two arrays are not sorted. In the example, the arrays are sorted, but this is not required.