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
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)