【问题标题】:Map a Complex Array映射一个复杂的数组
【发布时间】:2014-12-06 04:42:56
【问题描述】:
    array = [{:variant_id=>51, :product_id=>14, :position=>2, :price=>80.0}, {:variant_id=>52, :product_id=>14, :position=>3, :price=>200.0}, {:variant_id=>14, :product_id=>5, :position=>1, :price=>0.0}, {:variant_id=>15, :product_id=>5, :position=>2, :price=>100.0}, {:variant_id=>16, :product_id=>5, :position=>3, :price=>210.0}, {:variant_id=>17, :product_id=>5, :position=>4, :price=>225.0}, {:variant_id=>63, :product_id=>17, :position=>2, :price=>100.0}]

每个 product_id 有 4 个变体。每个变体都有一个位置(1、2、3 或 4)。每个变体都有一个价格。

例子

产品编号:5
有 variant_id:10、11、12、13
variant_id:10 的价格为 100 美元
variant_id:11 的价格为 200 美元
variant_id:12 的价格为 300 美元
variant_id: 13 的价格为 $400

我想将这个哈希数组映射到一个哈希数组,其结构如下 {product_id:5,价格:“100|200|300|400”]

【问题讨论】:

    标签: ruby-on-rails ruby arrays sorting mapping


    【解决方案1】:

    看起来像 group_by、map 和 reduce,朋友应该在这里帮助你。

    这应该可以工作

    grouped = array.group_by {|x| x[:product_id]}
    

    这会给你一个带有product_id => hashes_with_this_product_id的哈希

    您现在可以映射和连接这些值

    grouped.map do |id, arr|
      prices = arr.map {|h| h[:price].to_s}.join('|')
      {product_id: id, price: prices}
    end
    

    我还没有测试过,但这应该对你有一点帮助

    【讨论】:

    • 已修复 :) 我实际上是在手机上写字。而且在这个东西上写代码真的很难。很高兴能帮到你。
    【解决方案2】:

    发布我的答案后,我注意到它与@Ismael 的答案几乎相同,他在几分钟前发布了该答案。因此,我更改了答案以说明另一种方法。在您选择我的答案后,我这样做了。如果您想将绿色复选标记移至 Ismael 的答案,或稍后可能添加的答案,请务必这样做。

    array = [{:variant_id=>51, :product_id=>14, :position=>2, :price=>80.0},
             {:variant_id=>52, :product_id=>14, :position=>3, :price=>200.0},
             {:variant_id=>14, :product_id=>5,  :position=>1, :price=>0.0},
             {:variant_id=>15, :product_id=>5,  :position=>2, :price=>100.0},
             {:variant_id=>16, :product_id=>5,  :position=>3, :price=>210.0},
             {:variant_id=>17, :product_id=>5,  :position=>4, :price=>225.0},
             {:variant_id=>63, :product_id=>17, :position=>2, :price=>100.0}]
    
    array.each_with_object({}) { |h,g|
      g.update({ h[:product_id] => h[:price].to_s }) { |_,o,n| "#{o}|#{n}" } }
       .map { |k,v| { product_id: k, price: v } }
      #=> [{:product_id=>14, :price=>"80.0|200.0"},
      #    {:product_id=>5,  :price=>"0.0|100.0|210.0|225.0"},
      #    {:product_id=>17, :price=>"100.0"}]
    

    这使用了Hash#update(又名Hash#merge!)的形式,它接受一个块。当哈希{h[:product_id] => h[:price].to_s}(其中harray的一个元素)被合并到初始空哈希g中时,如果两个哈希都包含键h[:product_id],则调用该块来确定合并哈希中该键的值。三个值被传递给块:共享键(我没有使用,所以我用占位符_替换了键的关联块变量),合并哈希中的当前值g,@ 987654331@(分配给块变量o)和要合并的哈希值h[:price].to_s(分配给块变量n)。如图所示,该值应为"#{o}|#{n}"

    第一步产生哈希:

    h = array.each_with_object({}) { |h,g|
      g.update({h[:product_id] => h[:price].to_s}) {|_,o,n| "#{o}|#{n}"}}
      #=> {14=>"80.0|200.0", 5=>"0.0|100.0|210.0|225.0", 17=>"100.0"}
    

    顺便说一句:你可以考虑在这里停下来。

    最后一步是将这个散列的每个键值对映射到一个散列,生成散列数组:

    h.map { |k,v| {product_id: k, price: v } }
    

    【讨论】:

    • 酷。 :) 我们的想法是一样的
    • Cary 再次拯救世界!非常感谢!
    猜你喜欢
    • 2012-10-16
    • 1970-01-01
    • 2010-11-21
    • 2011-02-25
    • 2012-04-02
    • 1970-01-01
    • 2021-08-15
    • 2014-03-02
    • 2012-04-19
    相关资源
    最近更新 更多