Check if two arrays contain the same elements in Ruby, RSpec or Test::Unit

Updated . Posted . Visible to the public.

RSpec 1, RSpec 2

To test whether two arrays have the same elements regardless of order, RSpec 1 and 2 give you the =~ matcher:

actual_array.should =~ expected_array

Rspec 3

With RSpec 3's expect syntax you can choose one of these two matchers:

expect(actual_array).to match_array(['1', '2', '3'])
expect(actual_array).to contain_exactly('1', '2', '3')

Note how match_array takes an argument, but contain_exactly takes a list of elements as varargs.

Test::Unit

If you install shoulda-matchers Show archive.org snapshot you can say:

assert_same_elements([:a, :b, :c], [:c, :a, :b])

Pure Ruby

It's a little tricky to emulate this check in plain Ruby (outside of a spec). If you're OK with ignoring duplicate elements and your element classes implement #hash Show archive.org snapshot correctly (e.g. Strings), you can say:

def same_elements?(array1, array2)
  array1.to_set == array2.to_set
end

If duplicate elements matter (e.g. you consider [1,1,2] not to have the same elements as [1,2]), emulate what RSpec does Show archive.org snapshot :

def difference_between_arrays(array1, array2)
  difference = array1.dup
  array2.each do |element|
    if index = difference.index(element)
      difference.delete_at(index)
    end
  end
  difference
end

def same_elements?(array1, array2)
  extra_items = difference_between_arrays(array1, array2)
  missing_items = difference_between_arrays(array2, array1)
  extra_items.empty? & missing_items.empty?
end
Profile picture of Henning Koch
Henning Koch
Last edit
Dominik Schöler
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2010-12-07 13:21)