0

.group_by文字列をキーとして、AR オブジェクトを値として、メソッドによって作成されたハッシュがあります。そして、フィールドが重複しているARオブジェクトを取り除きたい(他のフィールドは同じかもしれないし、そうでないかもしれない)

このスニペットを作成した質問を明確にするために:

require 'ostruct'   

def os_new(fid); OpenStruct.new(fid: fid, rand: rand(100)); end                                                                                                                                              
a = [os_new(1), os_new(2), os_new(3)]                                                                                                                                                
b = [os_new(3), os_new(3), os_new(2)]                                                                                                                                                
c = [os_new(5), os_new(5), os_new(5), os_new(5)] 

grouped_hash = { a: a, b: b, c: c} 

grouped_hashここは:

# {:a=>[#<OpenStruct fid=1, rand=7>, #<OpenStruct fid=2, rand=50>, #<OpenStruct fid=3, rand=13>], 
#  :b=>[#<OpenStruct fid=3, rand=51>, #<OpenStruct fid=3, rand=58>, #<OpenStruct fid=2, rand=88>], 
#  :c=>[#<OpenStruct fid=5, rand=40>, #<OpenStruct fid=5, rand=8>, #<OpenStruct fid=5, rand=45>, #<OpenStruct fid=5, rand=72>]} 

今、結果fidとして、各キーに一意の s を持つハッシュが必要です。

# {:a=>[#<OpenStruct fid=1, rand=7>, #<OpenStruct fid=2, rand=50>, #<OpenStruct fid=3, rand=13>], 
#  :b=>[#<OpenStruct fid=3, rand=51>, #<OpenStruct fid=2, rand=88>], 
#  :c=>[#<OpenStruct fid=5, rand=40>]} 

私のソリューションにはいくつかのアクションが必要で、見栄えが悪いです。

grouped_hash.each_value do |value|                                                                                                                                                     
  fids = []
  value.delete_if do |object|
    if fids.include? object.fid                                                                                                                                                            
      true
    else                                                                                                                                                                                   
      fids << object.fid
      false
    end                                                                                                                                                                                
  end
end

最もエレガントな(おそらく1ライナー)効率的な方法(ハッシュの再作成なし)を探しています。

4

3 に答える 3

2

grouped_hash.each_value(&:uniq)

AR オブジェクトによると、Rails は意図的に等値チェックを ID 列に委譲します。2 つの AR オブジェクトに同じ値が含まれていることを知りたい場合は、両方で #attributes を呼び出した結果を比較してください。

于 2015-01-09T09:00:26.620 に答える
1

厳密には 1 行ではありません (ただし、1 行で記述することもできます)。

grouped_hash.inject({}) do |hash, element|
  hash[element.first] = element.last.uniq(&:fid)
  hash
end
于 2015-01-09T09:03:30.310 に答える
0

Tenshokatafrakt (ありがとうございます) の回答を組み合わせて、次のようにしました。

grouped_hash.each_value { |v| v.uniq!(&:fid) }
于 2015-01-09T16:34:50.350 に答える