2017-06-30 43 views
1

我有一個數組分組子陣列相同的項目紅寶石

arr = [["cat", "15"], ["dog", "17"], ["cat", "20"], ["cat", "356"], ["dog", "89"], ["bird", "65"], ["dog", "336"], ["bird", "545"]] 

我想通過同第一項目組子陣,我只需要得到類似的東西:

arr = [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65","545"]] 

誰能幫忙?

+2

以'group_by'開頭 –

+0

您到目前爲止嘗試過什麼? – Stefan

+3

_「**組**子** ** **相同​​*第一**項」_→'group_by(&:first)'應該讓你開始 – Stefan

回答

2

下一次,這將是巨大的,如果你加你是試圖做的就是你想要的一些步驟,這裏是一個快速的解決方案:

> arr.group_by(&:shift).map(&:flatten) 
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]] 

但是,這會產生變異原arr

@ Md.FarhanMemon有沒有發生變異

+2

好的值得添加一個警告,它會改變原始數組。 –

+2

是的,我們需要深入這裏。而這一個不會做任何事情:) –

+0

但不執行它。留下他_something_去做:) –

2

替代的解決方案很好的解決方案,不改變原來的對象,並不需要DUP ..

arr.group_by(&:first).map{ |k, v| [k] + v.map { |e| e[1] } } 
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]] 

OR

arr.group_by(&:first).map{ |k, v| [k] + v.map(&:last) } 
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]] 
+0

或'[k] + v.map(&:last)'或'v.map(&:last).unshift(k)' – Stefan

+0

我編輯了你的答案, '|'是一個錯字,但也許是'Array#|'? – Stefan

+0

@Stefan它不是一個錯字:)並且是可以有多種變體來映射第二部分..'v.map(&:last)'看起來更短,儘管 –

1

另一種方式是通過哈希將所有值:

animals = arr.each_with_object(Hash.new{|h, k| h[k] = []}) do |(animal_name, value), obj| 
    obj[animal_name] << value 
end 
#=> {"cat"=>["15", "20", "356"], "dog"=>["17", "89", "336"], "bird"=>["65", "545"]} 

然後將其轉換爲預期輸出:

animals.map(&:flatten) 
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]] 
2

其他的答案已經提供了完美好的解決方案我正在發佈這個文件來顯示(鮮爲人知的?)assoc方法的應用程序。它使用給定的第一個元素掃描數組的子陣列,就好像數組是散列一樣。這可以被用於填充結果array

result = [] 
arr.each do |name, value| 
    group = result.assoc(name) 
    if group 
    group << value 
    else 
    result << [name, value] 
    end 
end 

result 
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]] 

的代碼可以進一步短路到:

arr.each_with_object([]) do |(name, value), result| 
    group = result.assoc(name) 
    group ? group << value : result << [name, value] 
end 
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]] 

assoc還可以用於容易地從檢索一個特定的「鍵」的值result array:

name, *values = result.assoc('cat') 
name #=> "cat" 
values #=> ["15", "20", "356"] 
+0

整潔。我認爲這是最有效的解決方案。 – Gerry