문제

내가 아는 한, 결과

["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 비교를 사용하여 문자열 복제를 제거합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top