Ruby의 개체 속성별 고유한 특성
하나 이상의 속성과 관련하여 고유한 배열의 개체를 선택하는 가장 우아한 방법은 무엇입니까?
이러한 객체는 ActiveRecord에 저장되므로 AR의 메서드를 사용하는 것도 좋습니다.
블록과 함께 사용:
@photos = @photos.uniq { |p| p.album_id }
추가합니다.uniq_by
메소드를 프로젝트의 배열에 추가합니다.와 유사하게 작용합니다.sort_by
.그렇게uniq_by
~하는 것입니다.uniq
~하듯이sort_by
~하는 것입니다.sort
용도:
uniq_array = my_array.uniq_by {|obj| obj.id}
구현:
class Array
def uniq_by(&blk)
transforms = []
self.select do |el|
should_keep = !transforms.include?(t=blk[el])
transforms << t
should_keep
end
end
end
현재 배열을 수정하는 대신 새 배열을 반환합니다.우리는 아직 작성하지 않았습니다.uniq_by!
방법이지만 당신이 원한다면 충분히 쉬울 것입니다.
편집: 부족 의견은 구현이 O(n^2)라고 지적합니다.(테스트되지 않은) 그런 것이 더 나을 것입니다...
class Array
def uniq_by(&blk)
transforms = {}
select do |el|
t = blk[el]
should_keep = !transforms[t]
transforms[t] = true
should_keep
end
end
end
데이터베이스 수준에서 수행:
YourModel.find(:all, :group => "status")
이 방법을 사용하여 배열에서 여러 특성 요소별로 고유한 항목을 선택할 수 있습니다.
@photos = @photos.uniq { |p| [p.album_id, p.author_id] }
나는 원래 사용할 것을 제안했습니다.select
배열에 메서드가 있습니다.위트:
[1, 2, 3, 4, 5, 6, 7].select{|e| e%2 == 0}
우리에게 주는[2,4,6]
뒤로.
하지만 첫 번째 개체를 원한다면,detect
.
[1, 2, 3, 4, 5, 6, 7].detect{|e| e>3}
우리에게 주는4
.
당신이 여기서 뭘 하려는 건지 잘 모르겠어요
저는 독특함을 강화하기 위해 해시를 사용하는 jmah의 방식을 좋아합니다.고양이 가죽을 벗기는 몇 가지 방법이 더 있습니다.
objs.inject({}) {|h,e| h[e.attr]=e; h}.values
좋은 1라인이지만, 저는 이것이 조금 더 빠를 수도 있다고 생각합니다.
h = {}
objs.each {|e| h[e.attr]=e}
h.values
objects.uniq {|obj| obj.attribute}
또는 보다 간결한 접근 방식:
objects.uniq(&:attribute)
제가 찾은 가장 우아한 방법은 블록을 사용한 스핀오프입니다.
enumerable_collection.uniq(&:property)
…더 잘 읽힙니다!
만약 내가 당신의 질문을 올바르게 이해했다면, 나는 마셜드 객체를 비교하여 속성이 다양한지 여부를 결정하는 준해키적 접근법을 사용하여 이 문제를 해결했습니다.다음 코드 끝에 있는 주입이 예입니다.
class Foo
attr_accessor :foo, :bar, :baz
def initialize(foo,bar,baz)
@foo = foo
@bar = bar
@baz = baz
end
end
objs = [Foo.new(1,2,3),Foo.new(1,2,3),Foo.new(2,3,4)]
# find objects that are uniq with respect to attributes
objs.inject([]) do |uniqs,obj|
if uniqs.all? { |e| Marshal.dump(e) != Marshal.dump(obj) }
uniqs << obj
end
uniqs
end
각 키에 대해 하나의 값만 포함하는 해시를 사용할 수 있습니다.
Hash[*recs.map{|ar| [ar[attr],ar]}.flatten].values
레일즈는 또한#uniq_by
방법.
참조: 매개 변수화된 Array#uniq(즉, uniq_by)
저는 jmah와 Head의 답변을 좋아합니다.하지만 그들은 배열 순서를 보존합니까?언어 사양에 해시 삽입 순서 보존 요구 사항이 작성되었기 때문에 루비의 최신 버전에서 사용할 수 있지만, 여기 순서를 보존하는 유사한 솔루션이 있습니다.
h = Set.new
objs.select{|el| h.add?(el.attr)}
액티브 지원 구현:
def uniq_by
hash, array = {}, []
each { |i| hash[yield(i)] ||= (array << i) }
array
end
이제 속성 값을 정렬할 수 있으면 다음 작업을 수행할 수 있습니다.
class A
attr_accessor :val
def initialize(v); self.val = v; end
end
objs = [1,2,6,3,7,7,8,2,8].map{|i| A.new(i)}
objs.sort_by{|a| a.val}.inject([]) do |uniqs, a|
uniqs << a if uniqs.empty? || a.val != uniqs.last.val
uniqs
end
이는 1-속성 고유에 대한 것입니다. 하지만 사전 편찬적 정렬에서도 동일한 작업을 수행할 수 있습니다.
어레이를 사용하지 않는 경우 세트를 통해 중복을 제거할 수도 있습니다.
set = Set.new
set << obj1
set << obj2
set.inspect
사용자 지정 개체의 경우 다음을 재정의해야 합니다.eql?
그리고.hash
언급URL : https://stackoverflow.com/questions/109781/uniq-by-object-attribute-in-ruby
'programing' 카테고리의 다른 글
'Microsoft' 유형에 대한 서비스가 없습니다.AsNetCore.MVC.기능 보기.'ITempDataDictionaryFactory'가 등록되었습니다. (0) | 2023.07.15 |
---|---|
Excel에서 SQL 실행이 임시 테이블을 사용할 수 없습니다. (0) | 2023.07.15 |
라즈베리 파이에서 운영체제 없이 C 프로그램을 실행하는 방법은 무엇입니까? (0) | 2023.07.15 |
C에서 문자열에 있는 문자의 발생 횟수 계산 (0) | 2023.07.15 |
Spring mvc : 기본 응답 형식을 xml에서 json으로 변경합니다. (0) | 2023.07.15 |