【问题标题】:Using inject with an array of hashes使用带有哈希数组的注入
【发布时间】:2013-07-17 09:22:18
【问题描述】:

我有一个哈希数组,每个哈希都有一个键 lol,它有一个整数值。我想对这些值求和,注入总是有效,但现在我得到一个例外:

array = [{lol: 1}, {lol: 2}]
array.inject {|memo, (key, value)| memo + value} =>
NoMethodError: undefined method `+' for {:lol=>1}:Hash
from (irb):26:in `block in irb_binding'
from (irb):26:in `each'
from (irb):26:in `inject'
from (irb):26

猪?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    您可以使用flat_map(&:values) 获取所有哈希值,然后使用inject(:+) 对它们求和。

    [{lol: 1}, {lol: 2}].flat_map(&:values).inject(:+)
    

    您的方法不起作用的原因是注入将产生每个哈希块,而不是数组中每个哈希的每个键/值对。如果你想保留你的解决方案,你会想要这样的东西:

    array.map {|hash| hash.inject(0) {|memo, (key, value)| memo + value } }.inject(:+)
    

    【讨论】:

    • +1,但我会这样写第二个 sn-p:array.inject(0) {|memo, h| memo + h[:lol] }。第一个也是inject(0, :+)。尽管 OP 似乎只想要“lol”键,所以:[{lol: 1}, {lol: 2}].map { |h| h[:lol] }.inject(0, :+)
    • 假设 :lol 是您唯一关心其值的键,绝对。
    • 比公认的答案长一点,但我学到了一些新东西,+1。
    【解决方案2】:

    来自.inject documentation

    如果没有显式指定memo的初始值,则collection的第一个元素作为memo的初始值。

    array.inject {|memo, (key, value)| memo + value}
    

    memo 的值是一个哈希值而不是一个数字。

    改正为

    array.inject(0) {|memo, hash| memo + hash[:lol]} # => 3
    

    【讨论】:

      【解决方案3】:

      如果您没有为inject 指定参数,则第一次迭代的备忘录对象的值是可枚举的第一个元素,在这种情况下是散列。所以你只需要将0 作为参数传递给inject

      array = [{lol: 1}, {lol: 2}]
      array.inject(0) { |sum, h| sum + h[:lol] }
      # => 3
      

      【讨论】:

      • 那是我的第一次尝试,但没有初始化,所以我搜索了一个也不起作用的键/值解决方案。非常简单的谢谢。
      猜你喜欢
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多