2015-01-09 87 views
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個散列每個鍵:

# {: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班輪)和有效的方式(沒有哈希重新創建)。

回答

2

grouped_hash.each_value(&:uniq)

根據AR對象,Rails的故意代表平等檢查標識列。如果您想知道兩個AR對象包含相同的值,則比較兩個調用#attributes的結果。

1

不完全的一行(儘管你可以在一行寫太):

grouped_hash.inject({}) do |hash, element| 
    hash[element.first] = element.last.uniq(&:fid) 
    hash 
end 
+0

我'已經更新了一個問題,以免被'id'弄糊塗並且證明每個對象中都有其他字段,所以'uniq'將不起作用 –

+0

'uniq(&:fid)'怎麼樣? (更新回答) – katafrakt

+0

謝謝!我明白了!你的解決方案重新創建一個哈希,所以我把它與@Tensho答案結合起來,得到我想要的 –

0

通過結合Tenshokatafrakt(謝謝你們)我做了這個答案:

grouped_hash.each_value { |v| v.uniq!(&:fid) }