13

私の知る限り、結果は

["a", "A"].uniq 

["a", "A"]

私の質問は:

["a", "A"].uniq で ["a"] または ["A"] のいずれかを取得するにはどうすればよいですか

4

7 に答える 7

42

これを行う別の方法があります。実際に、各要素を評価するために使用できる ブロックをuniqorに渡すことができます。uniq!

["A", "a"].uniq { |elem| elem.downcase }  #=>  ["A"]

また

["A", "a"].uniq { |elem| elem.upcase }  #=>  ["A"]

ただし、この場合、すべて大文字と小文字が区別されないため、常に配列が返されます["A"]

于 2013-10-15T22:16:06.793 に答える
18

最初に大文字と小文字を一致させてください。

例えば:

["a","A"].map{|i| i.downcase}.uniq

編集: mikejが示唆するように、返される要素が元の配列とまったく同じでなければならない場合、これはあなたのためにそれを行います:

a.inject([]) { |result,h| result << h unless result.map{|i| i.downcase}.include?(h.downcase); result }

mikejを満たすべきEdit2ソリューション:-)

downcased = [] 
a.inject([]) { |result,h| 
        unless downcased.include?(h.downcase);
            result << h
            downcased << h.downcase
        end;
        result}
于 2009-07-09T11:45:36.253 に答える
7

大文字と小文字を区別した(たとえば、小文字の)値と実際の値の間にマッピング(ハッシュ)を作成し、ハッシュから値だけを取得することができます。

["a", "b", "A", "C"]\
.inject(Hash.new){ |h,element| h[element.downcase] = element ; h }\
.values

指定された単語の最後の出現を選択します(大文字と小文字は区別されません)。

["A", "b", "C"]

最初の出現が必要な場合:

["a", "b", "A", "C"]\
.inject(Hash.new){ |h,element| h[element.downcase] = element  unless h[element.downcase]  ; h }\
.values
于 2009-07-09T12:30:17.423 に答える
5
["a", "A"].map{|x| x.downcase}.uniq
=> ["a"]

また

["a", "A"].map{|x| x.upcase}.uniq
=> ["A"]
于 2009-07-09T11:46:18.517 に答える
4

ActiveSupport を使用している場合は、 uniq_by を使用できます。最終出力の大文字小文字には影響しません。

['A','a'].uniq_by(&:downcase) # => ['A']
于 2013-10-08T15:11:30.270 に答える
2

もう少し効率的な方法は、ハッシュで一意のキーを使用することです。これを確認してください。

["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"]

特に大きな配列の場合、毎回インクルードを使用して配列を検索しないため、これは高速になるはずです?

乾杯...

于 2009-10-02T09:31:00.733 に答える
0

より一般的な解決策 (ただし、最も効率的ではありません):

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メソッドは、大文字と小文字を区別しない比較を使用して文字列の重複を削除します。

于 2009-07-09T12:22:31.757 に答える