Ruby数组相等

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

mu *_*ort 8

标准库中有一个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?应该以相同的方式行事,除非有充分的理由让它们变得不同.


Kai*_*Kai 5

要查看两个数组是否包含相同的元素(无论顺序如何),可以使用 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)