2009-10-30 6 views
5

나는 여러 가지를 위해 트위터를 검색 할 순간에 Ruby 앱을 쓰고있다. 내가 직면하게 될 문제 중 하나는 서로 가까운 거리에서 서로 검색 결과를 공유하는 것입니다. 결과는 각각 하나의 트윗 인 객체의 배열로 반환됩니다. 나는 모든 중복을 제거한 배열을 반환하는 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 

루비는 클래스 컨텍스트에 따라 == 연산자를 재정의 할 것을 권장합니다.

특정한 경우 트위터 결과를 나타내는 개체를 만들고 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'이어야한다고 생각한다. –

+0

네, 맞습니다. 결정된. –

+1

'hash'메소드를 덮어 쓰지 않고도이 작업을 수행 할 수 없습니다. http://www.rabbitcreative.com/2008/01/23/comparing-custom-objects-in-ruby-using-uniq/을 참조하십시오. – spier

0

Array.uniq는 (객체의 콘텐츠에 기초 eql?의 의미있는 구현을 제공 가정) 메모리의 비교 내용에 기초하지 위치를 의미 객체의 eql? 또는 == 방법을 통해 중복 검출 믿는다.

6

, 그것은 보인다 (1.9.3 적어도), Array.uniq은 객체도이 있다고 가정합니다 .eql? 또는 == 외에도 #hash 메서드의 의미있는 구현.

관련 문제