ben*_*ben 2 ruby arrays equals
我有一个数组数组,称为guid_pairs:
[['a','b','c'],['c','g'],['z','f','b']]
Run Code Online (Sandbox Code Playgroud)
我也有一个数组,名为array_to_check:
['c','a','b']
Run Code Online (Sandbox Code Playgroud)
如何确定数组guid_pairs是否具有等于的元素array_to_check.平等不应该考虑数组元素的位置.
在此示例中,检查应返回,true因为guid_pairs包含['a','b','c']匹配的元素['c','a','b'].
我试过这个,但它似乎总是会返回,false即使它应该返回true:
guid_pairs.any?{|pair| pair.eql?(array_to_check)}
Run Code Online (Sandbox Code Playgroud)
我使用的是Ruby 1.9.2
标准库中有一个set类,使用sets很符合你的意图:
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) }
Run Code Online (Sandbox Code Playgroud)
这将留下aain 的匹配元素元素the_match.如果你只对存在感兴趣那么你可以简单地检查一下真实性the_match; 或使用any?(感谢提醒Michael Kohl,我经常忘记Enumerable中的一些内容):
aa.any? { |x| find_this == Set.new(x) }
Run Code Online (Sandbox Code Playgroud)
没有技巧,没有魔法,并且使用Set表明你实际上是将数组作为集合进行比较.
顺便说一下,您尝试的解决方案
guid_pairs.any? { |pair| pair.eql?(array_to_check) }
Run Code Online (Sandbox Code Playgroud)
不起作用,因为数组按顺序逐个元素进行比较,因此两个数组相等,当且仅当它们具有相同顺序的相同元素时.在对文档eql?可以更清楚:
如果self和other是同一个对象,或者两个数组都具有相同的内容,则返回true.
但==文档很好而且清晰:
如果两个数组包含相同数量的元素,并且每个元素等于(根据Object.==)另一个数组中的相应元素,则它们是相等的.
我们可以看看Object#eql?但是要澄清一些:
这个eql?如果obj和anObject具有相同的值,则method返回true.由Hash用于测试成员的相等性.对于Object类的对象,eql?是==的同义词.子类通常延续这一传统,但也有例外.
所以==并且eql?应该以相同的方式行事,除非有充分的理由让它们变得不同.
要查看两个数组是否包含相同的元素(无论顺序如何),可以使用 XOR(异或)运算。它将返回一个数组,其中仅包含一个数组中的元素,而不包含另一个数组中的元素。如果 XOR 的长度为零,则输入数组包含相同的元素。
def xor(a, b)
(a | b) - (a & b)
end
guid_pairs.any? { |pair| xor(pair, array_to_check).length != 0 }
Run Code Online (Sandbox Code Playgroud)