2012-09-22 68 views
0

我在比較對象數組,並且我有一個方法確定兩個元素是否相等。我想在這兩個數組的每一對元素上調用這個方法,是否有一個優雅的方法來找到真值(即如果每個數組中的所有元素都是等價的,否則返回false)Ruby-優雅地調用兩個數組元素的方法

這是我有什麼目前:

c = false 
self.children.zip(other.children).each do |s,o| 
    c = s.equiv o # I need a good way to store this result 
    break if not c 
end 

我希望我可以做這樣的事情:

c = self.children.zip(other.children).each{|s,o| s.equiv o} 

任何幫助,將不勝感激。

回答

2

那麼你有Enumerable#all?

c = self.children.zip(other.children).all? {|s,o| s.equiv o} 
+0

謝謝,我甚至都不知道?存在 –

+0

查看OP對jmdeldin爲什麼不能使用==的答案的評論。 – sawa

+0

@ HunterMcMillen ..你可能沒有在Ruby的標準'Array'文檔中找到它,因爲它出現在Array,Hash,Range等包含的'Enumerable'混合中。它增加了許多有用的方法。檢出我發佈的鏈接以瞭解這些方法。 – rubyprince

0

我想如果你用map代替each,那麼c就是你要找的數組。我不能100%確定,因爲我無法立即測試,並且我知道zip有一些問題。

2

如何使用all?

c = self.children.zip(other.children).all?{|s,o| s.equiv o} 
+0

謝謝,我甚至都不知道這一切?存在。 –

1

一個更好的解決方法就是定義在你的對象==。然後,您可以使用Array#==來完成您的工作,因爲它已經進行了所有配對比較。

這裏有一個簡單的例子:

class Widget 
    attr_reader :name 

    def initialize(name) 
    @name = name 
    end 

    def ==(other) 
    @name == other.name 
    end 
end 

if $0 == __FILE__ 
    require 'minitest/autorun' 

    describe 'widget arrays' do 
    let(:some_widgets) { %w(foo bar baz).map { |name| Widget.new(name) } } 
    let(:diff_widgets) { %w(bar baz spam).map { |name| Widget.new(name) } } 

    it 'returns true if the widget arrays are the same' do 
     (some_widgets == some_widgets).must_equal true 
    end 

    it 'returns false if the widget arrays are different' do 
     (some_widgets == diff_widgets).must_equal false 
    end 
    end 
end 

您只要致電some_widgets == my_other_widgets每個元素進行比較。

+0

redifining ==的問題是我無法區分對象。我定義了'equiv',而不是因爲我的任務,我仍然需要能夠區分具有相同值的相同對象和對象的引用。謝謝你的想法。 –

+1

@HunterMcMillen:當你重新定義'=='(或任何其他的等號方法)時,你可以**分開對象。在這個例子中,如果你需要確定對象是否是相同的引用,可以通過'Array#eql?'使用'Object#eql?'(例如'[Widget.new('foo')]。eql?[ Widget.new('foo')]#=> false')。 – jmdeldin

+0

@jmeldin我看到你在說什麼,但我不想重寫'==',我希望它保持不變,這就是我上面提到的。 –

相關問題