문제
내가 아는 한, 결과
["a", "A"].uniq
~이다
["a", "A"]
내 질문은 다음과 같습니다.
"A", "A"
해결책
케이스를 먼저 일관성있게 만드십시오.
예 :
["a","A"].map{|i| i.downcase}.uniq
편집하다: Mikej가 제안한대로, 반환 된 요소는 원래 배열에서와 정확히 동일해야한다면, 이렇게합니다.
a.inject([]) { |result,h| result << h unless result.map{|i| i.downcase}.include?(h.downcase); result }
edit2 mikej를 만족시켜야하는 해결책 :-)
downcased = []
a.inject([]) { |result,h|
unless downcased.include?(h.downcase);
result << h
downcased << h.downcase
end;
result}
다른 팁
당신이 할 수있는 또 다른 방법이 있습니다. 실제로 블록을 전달할 수 있습니다 uniq
또는 uniq!
각 요소를 평가하는 데 사용할 수 있습니다.
["A", "a"].uniq { |elem| elem.downcase } #=> ["A"]
또는
["A", "a"].uniq { |elem| elem.upcase } #=> ["A"]
그러나이 경우 모든 것이 케이스 둔감이므로 항상 배열을 반환합니다. ["A"]
케이스 정규화 된 (예 : 다운 케이스) 값과 실제 값 사이의 매핑 (해시)을 빌드 한 다음 해시에서 값 만 가져갈 수 있습니다.
["a", "b", "A", "C"]\
.inject(Hash.new){ |h,element| h[element.downcase] = element ; h }\
.values
주어진 단어의 마지막 발생을 선택합니다 (Case Insensentitive).
["A", "b", "C"]
첫 번째 발생을 원한다면 :
["a", "b", "A", "C"]\
.inject(Hash.new){ |h,element| h[element.downcase] = element unless h[element.downcase] ; h }\
.values
["a", "A"].map{|x| x.downcase}.uniq
=> ["a"]
또는
["a", "A"].map{|x| x.upcase}.uniq
=> ["A"]
ActiveSupport를 사용하는 경우 사용할 수 있습니다 UNIQ_BY. 최종 출력의 경우에는 영향을 미치지 않습니다.
['A','a'].uniq_by(&:downcase) # => ['A']
좀 더 효율적이고 방법은 해시에서 Uniq 키를 사용하는 것입니다.
["a", "A"].inject(Hash.new){ |hash,j| hash[j.upcase] = j; hash}.values
이 경우 마지막 요소를 반환합니다
["A"]
사용하는 동안 ||= 할당 연산자 :
["a", "A"].inject(Hash.new){ |hash,j| hash[j.upcase] ||= j; hash}.values
이 경우 첫 번째 요소를 반환합니다
["a"]
특히 큰 배열의 경우 사용할 때마다 배열을 검색하지 않으므로 더 빠릅니다. 포함?
건배...
보다 일반적인 솔루션 (가장 효율적이지는 않지만) :
class EqualityWrapper
attr_reader :obj
def initialize(obj, eq, hash)
@obj = obj
@eq = eq
@hash = hash
end
def ==(other)
@eq[@obj, other.obj]
end
alias :eql? :==
def hash
@hash[@obj]
end
end
class Array
def uniq_by(eq, hash = lambda{|x| 0 })
map {|x| EqualityWrapper.new(x, eq, hash) }.
uniq.
map {|x| x.obj }
end
def uniq_ci
eq = lambda{|x, y| x.casecmp(y) == 0 }
hash = lambda{|x| x.downcase.hash }
uniq_by(eq, hash)
end
end
그만큼 uniq_by
메소드는 평등을 확인하는 람다와 해시를 반환하는 람다를 사용하고 해당 데이터에 의해 정의 된대로 중복 객체를 제거합니다.
그 위에 구현되었습니다 uniq_ci
메소드는 Case Insensitive 비교를 사용하여 문자열 복제를 제거합니다.