私の知る限り、結果は
["a", "A"].uniq
は
["a", "A"]
私の質問は:
["a", "A"].uniq で ["a"] または ["A"] のいずれかを取得するにはどうすればよいですか
これを行う別の方法があります。実際に、各要素を評価するために使用できる ブロックをuniq
orに渡すことができます。uniq!
["A", "a"].uniq { |elem| elem.downcase } #=> ["A"]
また
["A", "a"].uniq { |elem| elem.upcase } #=> ["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 }
mikejを満たすべきEdit2ソリューション:-)
downcased = []
a.inject([]) { |result,h|
unless downcased.include?(h.downcase);
result << h
downcased << h.downcase
end;
result}
大文字と小文字を区別した(たとえば、小文字の)値と実際の値の間にマッピング(ハッシュ)を作成し、ハッシュから値だけを取得することができます。
["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
["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']
もう少し効率的な方法は、ハッシュで一意のキーを使用することです。これを確認してください。
["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
メソッドは、大文字と小文字を区別しない比較を使用して文字列の重複を削除します。