2011-06-15 260 views
2

我有數組的數組,稱爲guid_pairs紅寶石陣列平等

[['a','b','c'],['c','g'],['z','f','b']] 

我也有一個數組,稱爲array_to_check

['c','a','b'] 

如何確定如果陣列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)} 

我使用Ruby 1.9.2

+4

這聽起來像你使用了錯誤的數據結構。考慮使用[sets](http://ruby-doc.org/stdlib/libdoc/set/rdoc/index.html)。 – 2011-06-15 05:19:03

回答

8

有一個在標準庫中的set class並使用套精美你的意圖相符:

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

,將離開的aa匹配元素元素the_match。如果你只對存在感興趣,那麼你可以簡單地檢查the_match的真實性;或使用any?(感謝您的提醒邁克爾·科爾,我經常忘記一些在可枚舉的東西):

aa.any? { |x| find_this == Set.new(x) } 

沒有章法,沒有魔法,並使用設置清楚地表明,你是,事實上,對比數組作爲集合。


BTW,你嘗試的解決方案:

guid_pairs.any? { |pair| pair.eql?(array_to_check) } 

不起作用,因爲數組元素比較逐元素,爲了使兩個數組相等,當且僅當他們在同一個相等的元素訂購。 documentation for eql?可能更清晰:

如果self和其他是相同的對象,或者都是具有相同內容的數組,則返回true。

== documentation是好的和明確:

兩個數組相等,如果它們包含相同數量的元素,並且如果每一個元素等於相應的元素(根據對象==。)在另一個陣列中。

我們可以看看Object#eql?一些澄清,但:

的EQL?如果obj和anObject具有相同的值,則方法返回true。 Hash使用它來測試成員是否相等。對於Object類的對象,eql?與==同義。子類通常會繼承這個傳統,但也有例外。

因此==eql?應該表現相同的方式,除非他們有很好的理由不同。

+1

如果你只關心真實性,你可以使用'any?'而不是'find'。 +1順便說一句,因爲我也喜歡爲此設置。 – 2011-06-15 06:42:24

+0

@邁克爾:謝謝你的提醒。我喜歡用Set來表達這種事物的表現力,說出你的意思和所有這些。 – 2011-06-15 06:48:57

1

一個可能的解決方案是將數組排序前(或者甚至在比較)比較:

guid_pairs.any?{|pair| pair.sort.eql?(array_to_check.sort)} 

注意,這可能不是最佳的解決方案 - 這將是更適合於有你的一排序的排序(儘管如此,它們是在你的用例中)。

0

您可以使用以下方法:

sorted_array_to_check = array_to_check.sort 
guid_pairs.any?{|pair| pair.sort.eql?(sorted_array_to_check)} 
0

三種解決方案:

class Array 
    def check1 other; other.any?{|e| self - e == e - self} end 
    def check2 other; other.any?{|e| self | e == self and e | self == e} end 
    def check3 other; other.any?{|e| self & e == self and e & self == e} end 
end 
array_to_check.check1(guid_pairs) # => true 
array_to_check.check2(guid_pairs) # => true 
array_to_check.check3(guid_pairs) # => true 

沒有定義一個方法(以下Josha的建議):

array_to_check.instance_eval{guid_pairs.any?{|e| self - e == e - self}} # => true 
    array_to_check.instance_eval{guid_pairs.any?{|e| self | e == self and e | self == e}} # => true 
    array_to_check.instance_eval{guid_pairs.any?{|e| self & e == self and e & self == e}} # => true 
+0

我會避免猴子修補陣列只是一個用例。 – 2011-06-15 05:21:56

+0

@Joshua我修改了我的答案。 – sawa 2011-06-15 05:28:37

4

要查看是否兩個數組包含相同的元素,無論順序如何,都可以使用異或(exclusive或)操作。它將返回一個只包含一個數組而不是另一個數組的元素的數組。如果XOR的長度爲零,則輸入數組包含相同的元素。

def xor(a, b) 
    (a | b) - (a & b) 
end 

guid_pairs.any? { |pair| xor(pair, array_to_check).length != 0 } 
1

兩個數組A的平等和B我通常使用:

if(((A-B) + (B-A)).blank?) 
    puts "equal" 
else 
    "unequal" 
end