2009-10-30 73 views
5

我正在編寫一個Ruby應用程序,它正在爲各種事情搜索Twitter。我將面臨的一個問題是在時間上彼此靠近的搜索之間共享結果。結果以對象數組的形式返回,每個對象都是單個推文。我知道ruby中的Array.uniq方法,它返回一個數組,其中刪除了所有重複項。刪除Ruby中的相同對象?

我的問題是這樣的。只要這些對象指向內存中的相同空間或者它們包含相同的信息,uniq方法是否會刪除重複項?

如果前者,根據內容從數組中刪除重複項的最佳方法是什麼?

回答

10

是否uniq的方法刪除重複 ,只要這些對象指向 相同的空間在存儲器中,或者它們 包含相同的信息?

該方法依賴於eql?方法,因此它刪除了a.eql?(b)返回true的所有元素。 確切的行爲取決於您正在處理的特定對象。

例如,如果字符串包含相同的文本而不管它們共享相同的內存分配,則認爲它們是相等的。

a = b = "foo" 
c = "foo" 

[a, b, c].uniq 
# => ["foo"] 

這對於核心對象的大部分都是如此,但對於紅寶石對象則不是這樣。

class Foo 
end 

a = Foo.new 
b = Foo.new 

a.eql? b 
# => false 

Ruby鼓勵您根據您的類上下文重新定義==運算符。

在您的具體情況下,我會建議創建一個代表Twitter結果的對象並實現您的比較邏輯,以便Array.uniq的行爲與您期望的相同。

class Result 

    attr_accessor :text, :notes 

    def initialize(text = nil, notes = nil) 
    self.text = text 
    self.notes = notes 
    end 

    def ==(other) 
    other.class == self.class && 
    other.text == self.text 
    end 
    alias :eql? :== 

end 

a = Result.new("first") 
b = Result.new("first") 
c = Result.new("third") 

[a, b, c].uniq 
# => [a, c] 
+0

謝謝,我在課堂上實現了所需的方法,現在它似乎正在工作。幸運的是,我真正需要比較的唯一的事情是每個推文的唯一ID :)我認爲'other.class = self.class'應該是'other.class == self.class'? – 2009-10-30 16:24:19

+0

是的,你是對的。固定。 – 2009-10-30 17:46:12

+1

我不能在不覆蓋'hash'方法的情況下工作。見http://www.rabbitcreative.com/2008/01/23/comparing-custom-objects-in-ruby-using-uniq/ – spier 2011-06-06 23:00:57

0

相信Array.uniq經由對象的eql?==方法,這意味着在存儲器其比較基於內容,而不是位置(假設對象提供基於內容的有意義的實施eql?)檢測重複。

6

爲別人絆就這個問題,看起來事情已經改變了一下,因爲這個問題是首先要求在新的Ruby版本(1.9.3至少),Array.uniq假設你的對象也有除了.eql?==之外,還有意義的實施#hash方法。