如果记录重复并且总和值如何删除记录:val

时间:2012-08-01 14:47:23

标签: ruby arrays

给出以下哈希数组:

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找到值的总和?

5 个答案:

答案 0 :(得分:2)

您可以将块传递给Array的方法uniq以确定唯一性。

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}]

答案 1 :(得分: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}

答案 2 :(得分:1)

使用group_by:

list.group_by{|x| x[:cod]}.map{|k, v| v[0].merge({:val => v.map{|x| x[:val]}.reduce(:+)})}

答案 3 :(得分: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值,最后将:+(加法)应用于它们以获得总和。

答案 4 :(得分: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}]