2017-05-11 5 views

Répondre

1

Ceci est une autre méthode qui est fait par itération à travers chaque élément de tableau:

animals = [['dogs', 4], ['cats', 3], ['dogs', 7]] 

result = Hash.new(0) 

animals.each do |animal| 
    result[animal[0]] += animal[1].to_i 
end 

p result 
+0

c'est bien. Je vous remercie! –

+0

Vous êtes les bienvenus CJ Jean :) –

4

Vous pouvez utiliser each_with_object:

=> array = [['dogs', 4], ['cats', 3], ['dogs', 7]] 
=> array.each_with_object(Hash.new(0)) do |(pet, n), accum| 
=> accum[pet] += n 
=> end 
#> {'dogs' => 11, 'cats' => 3} 
+0

Je suis d'accord, les noms de blocs seraient mieux lire –

-1

Vous pouvez utiliser la méthode to_h si vous utilisez r uby < = 2,1.

Par exemple:

animals = [['dogs', 4], ['cats', 3], ['dogs', 7]] 
animals.group_by(&:first).map { |k,v| [k,v.transpose.last.reduce(:+)]}.to_h # return {"dogs"=>11, "cats"=>3} 
+0

http://stackoverflow.com/questions/43906745/-there-a-way-to-convert-this-array-to-a -hash-without-the-injection-method # comment74846947_43906834 –

+0

Je répare la réponse. – mijailr

+0

'réduire' est un alias de' injecter' –

3

J'utilisé Enumerable#group_by. Une meilleure façon est d'utiliser un hachage de comptage, ce que @ Зелёный a fait.

animals = [['dogs', 4], ['cats', 3], ['dogs', 7]] 

animals.group_by(&:first).tap { |h| h.keys.each { |k| h[k] = h[k].transpose[1].sum } } 
    #=> {"dogs"=>11, "cats"=>3} 
2
data = [['dogs', 4], ['cats', 3], ['dogs', 7]] 
data.dup 
    .group_by(&:shift) 
    .map { |k, v| [k, v.flatten.reduce(:+)] } 
    .to_h 

Avec Hash#merge:

data.reduce({}) do |acc, e| 
    acc.merge([e].to_h) { |_, v1, v2| v1 + v2 } 
end 

data.each_with_object({}) do |e, acc| 
    acc.merge!([e].to_h) { |_, v1, v2| v1 + v2 } 
end