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

将动物转换为:

{'dogs' => 11, 'cats' => 3}
4

5 回答 5

4

您可以使用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}
于 2017-05-11T05:04:25.450 回答
3

我使用了 Enumerable#group_by。更好的方法是使用计数哈希,@Зелёный 已经这样做了。

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}
于 2017-05-11T05:07:25.080 回答
2
data = [['dogs', 4], ['cats', 3], ['dogs', 7]]
data.dup
    .group_by(&:shift)
    .map { |k, v| [k, v.flatten.reduce(:+)] }
    .to_h

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
于 2017-05-11T05:32:16.337 回答
1

这是通过遍历每个数组元素完成的另一种方法:

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
于 2017-05-11T04:59:48.413 回答
-1

to_h如果您使用的是 ruby​​ <= 2.1,则可以使用该方法。

例如:

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}
于 2017-05-11T05:06:32.633 回答