I have an array of arrays, called guid_pairs
:
[['a','b','c'],['c','g'],['z','f','b']]
I also have an array, called array_to_check
:
['c','a','b']
How can I determine if the array guid_pairs
has an element that is equal to array_to_check
. Equality should not consider the position of the array elements.
In this example, the check should return true
because guid_pairs
contains the element ['a','b','c']
, which matches ['c','a','b']
.
I have tried this, but it seems to always return false
even when it should return true
:
guid_pairs.any?{|pair| pair.eql?(array_to_check)}
I am using Ruby 1.9.2
There is a set class in the standard library and using sets nicely matches your intent:
require 'set'
a = ['c','a','b']
aa = [['a','b','c'],['c','g'],['z','f','b']]
find_this = Set.new(a)
the_match = aa.find { |x| find_this == Set.new(x) }
That will leave the matching element element of aa
in the_match
. If you're only interested in existence then you can simply check the truthiness of the_match
; or use any?
:
aa.any? { |x| find_this == Set.new(x) }
No tricks, no magic, and using Set makes it clear that you are, in fact, comparing the arrays as sets.
BTW, your attempted solution:
guid_pairs.any? { |pair| pair.eql?(array_to_check) }
doesn't work because arrays compare element-by-element in order so two arrays are equal if and only if they have equal elements in the same order. The documentation for eql?
could be clearer:
Returns true if self and other are the same object, or are both arrays with the same content.
But the ==
documentation is nice and clear:
Two arrays are equal if they contain the same number of elements and if each element is equal to (according to Object.==) the corresponding element in the other array.
We can look to Object#eql? for some clarification though:
The eql? method returns true if obj and anObject have the same value. Used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition, but there are exceptions.
So ==
and eql?
should behave the same way unless there is a good reason for them to be different.