Read more

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

Henning Koch
December 07, 2010Software engineer at makandra GmbH

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

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

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
Posted by Henning Koch to makandra dev (2010-12-07 14:21)