2

次のハッシュ配列があるとします。

list=[
  {:cod => "0001", :name => "name1", :val => 10},
  {:cod => "0001", :name => "name1", :val => 12},
  {:cod => "0002", :name => "name2", :val => 13},
  {:cod => "0002", :name => "name2", :val => 14},
  {:cod => "0002", :name => "name2", :val => 14},
  {:cod => "0004", :name => "name4", :val => 16},
  {:cod => "0004", :name => "name4", :val => 16},
  {:cod => "0004", :name => "name4", :val => 17},
  {:cod => "0005", :name => "name5", :val => 17},
  {:cod => "0005", :name => "name5", :val => 17},
  {:cod => "0005", :name => "name5", :val => 17},
  {:cod => "0006", :name => "name6", :val => 110},
  {:cod => "0006", :name => "name6", :val => 10},
]

重複したレコードを削除するにはどうすればよいですか?

また、キーを使用して値の合計を見つけるにはどうすればよい:valですか?

4

5 に答える 5

2

ブロックをuniqArray のメソッドに渡して、一意性を判断できます。

list.uniq { |h| h[:val] }

=> [{:cod=>"0001", :name=>"name1", :val=>10},
 {:cod=>"0001", :name=>"name1", :val=>12},
 {:cod=>"0002", :name=>"name2", :val=>13},
 {:cod=>"0002", :name=>"name2", :val=>14},
 {:cod=>"0004", :name=>"name4", :val=>16},
 {:cod=>"0004", :name=>"name4", :val=>17},
 {:cod=>"0006", :name=>"name6", :val=>110}]
于 2012-08-01T15:27:49.803 に答える
1
list.map do |a|
  list.select { |b| b[:cod] == a[:cod] && b[:name] == a[:name] } \
       .reduce { |res, c| {:cod  => c[:cod], :name => c[:name], :val => ((res[:val] + c[:val]) || c[:val])} }
end.uniq { |h| h[:cod]}.each {|c| puts c.inspect}

出力:

{:name=>"name1", :cod=>"0001", :val=>22}
{:name=>"name2", :cod=>"0002", :val=>41}
{:name=>"name4", :cod=>"0004", :val=>49}
{:name=>"name5", :cod=>"0005", :val=>51}
{:name=>"name6", :cod=>"0006", :val=>120}
于 2012-08-01T15:39:12.217 に答える
1

group_by を使用します。

list.group_by{|x| x[:cod]}.map{|k, v| v[0].merge({:val => v.map{|x| x[:val]}.reduce(:+)})}
于 2012-08-02T01:23:13.177 に答える
1

これまでの回答に基づいて、「重複レコードを削除する」とは実際に何を意味するのかについて混乱があります。あなたが意味することの私の解釈は、完全に重複しているレコードのみを削除したいということです。もしそうなら、提示された他の解決策よりもはるかに簡単です:

list.uniq

これは以下を返します:

[{:cod=>"0001", :name=>"name1", :val=>10},
 {:cod=>"0001", :name=>"name1", :val=>12},
 {:cod=>"0002", :name=>"name2", :val=>13},
 {:cod=>"0002", :name=>"name2", :val=>14},
 {:cod=>"0004", :name=>"name4", :val=>16},
 {:cod=>"0004", :name=>"name4", :val=>17},
 {:cod=>"0005", :name=>"name5", :val=>17},
 {:cod=>"0006", :name=>"name6", :val=>110},
 {:cod=>"0006", :name=>"name6", :val=>10}]

一意のレコードのフィールドの合計が必要な場合は、次の:valようにすることができます。

list.uniq.map{|h| h[:val]}.reduce(:+)

それは(上記のように)一意の要素を取得し:val、それぞれから値を取得し、最後にそれらに適用:+(加算)して合計を取得します。

于 2012-08-02T02:46:57.587 に答える
1
list.uniq.group_by { |e| [e[:cod], e[:name]] }.map do |k, v|
  {k => v.map { |h| h[:val] }.reduce(:+)}
end

=> [{["0001", "name1"]=>22}, {["0002", "name2"]=>27}, {["0004", "name4"]=>33}, {["0005", "name5"]=>17}, {["0006", "name6"]=>120}]
于 2012-08-02T14:14:27.330 に答える