2012-08-01 25 views
2

鑑於哈希以下數組:如何刪除記錄,如果它是複製和和值:VAL

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的值的總和?

+3

你能澄清這個問題嗎?重複的最終總和值:val? – 2012-08-01 14:51:22

+0

這也是一個數組,而不是散列。 – Ultimation 2012-08-01 15:11:12

+0

我們都在回答不同的問題。你是否希望根據具有重複的':val'字段,重複的':cod'-':name'對,或者整個哈希是相同的(或其他)來刪除記錄? – 2012-08-02 04:42:25

回答

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

使用GROUP_BY:

list.group_by{|x| x[:cod]}.map{|k, v| v[0].merge({:val => v.map{|x| x[:val]}.reduce(:+)})} 
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值,最後施加:+(加法)來他們得到的總和。

+0

如果真的那麼簡單,那就太好了!這給出了所有:val的總和,而不是每個唯一的ID。 – pguardiario 2012-08-02 08:55:46

+0

@pguardiario我不確定你的意思。它的確如我所說的那樣做:它丟棄重複的「行」(散列,其中':cod',':name'和':val'全部三個相同),然後添加':val'字段依然存在。 – 2012-08-02 16:52:41

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