【问题标题】:Get array from hash with arrays as values从以数组为值的哈希中获取数组
【发布时间】:2017-07-04 21:32:13
【问题描述】:

给定以下哈希hash,其中键作为符号,值作为数组:

hash
#=> {:stage_item=>[:stage_batch_id, :potential_item_id], :item=>[:id, :size, :color, :status, :price_sold, :sold_at], :style=>[:wholesale_price, :retail_price, :type, :name]}

我如何获得一个仅将值(数组)相加的数组?

我知道我可以使用#each_with_object#flatten

hash.each_with_object([]) { |(k, v), array| array << v }.flatten
#=> [:stage_batch_id, :potential_item_id, :id, :size, :color, :status, :price_sold, :sold_at, :wholesale_price, :retail_price, :type, :name]

但我希望只有 #each_with_object 可以工作:

hash.each_with_object([]) { |(k, v), array| array += v }
#=> []

虽然每个 with 对象的重点是它跟踪累加器(在这种情况下名为 array),所以我可以像下面的示例一样 += 它:

arr = [1,2,3]
#=> [1, 2, 3]
arr += [4]
#=> [1, 2, 3, 4]

我错过了什么?

【问题讨论】:

    标签: arrays ruby hash enumerable


    【解决方案1】:

    Array &lt;&lt; .. 就地更改原始数组:

    irb(main):014:0> a = original = []
    => []
    irb(main):015:0> a << [1]
    => [[1]]
    irb(main):016:0> a
    => [[1]]
    irb(main):017:0> original
    => [[1]]
    irb(main):018:0> a.equal? original  # identity check
    => true
    

    Array += .. 在不改变原数组的情况下返回一个新数组:

    irb(main):019:0 a = original = []
    => []
    irb(main):020:0> a += [1]
    => [1]
    irb(main):021:0> a
    => [1]
    irb(main):022:0> original
    => []
    irb(main):023:0> a.equal? original
    => false
    

    根据Enumerable#each_with_object documentation

    使用任意对象迭代每个元素的给定块 给定,并返回最初给定的对象。

    如果没有给出块,则返回一个枚举器。

    所以,如果是+=,则返回未修改的初始空数组。


    顺便说一句,您可以简单地使用Hash#values method,而不是使用each_with_object,它会返回一个填充了哈希值的新数组:

    hash.values.flatten
    

    【讨论】:

      【解决方案2】:

      如果你坚持使用Array#+,实际上inject会更合适:

      hash.inject([]) { |a, (_, v)| a + v }
      

      您通常使用each_with_object 而不是inject 的原因是,如果您想就地累积结果而不是使用块的返回值作为累加器。在这种情况下,array1 + array2 返回连接,因此您不需要使用修改备忘录对象的运算符(或方法),因为 Array#+ 返回您想要输入下一个循环的内容。

      虽然我们在这里,但这些会更简单:

      hash.values.flatten
      hash.values.inject(:+)
      h.values.flat_map(&:itself)
      

      如果您真的喜欢调用该方法,第二个甚至使用Array#+

      【讨论】:

        猜你喜欢
        • 2012-08-17
        • 2018-12-11
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 2021-07-16
        • 2014-04-14
        • 1970-01-01
        • 2019-06-03
        相关资源
        最近更新 更多