映射复杂数组

时间:2014-10-10 22:50:19

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

    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,11
variant_id:10的价格为100美元 variant_id:11的价格为200美元 variant_id:12的价格为300美元 variant_id:13的价格为400美元

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

2 个答案:

答案 0 :(得分: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

我还没有测试,但这应该对你有所帮助

答案 1 :(得分:1)

在发布我的回答之后,我注意到它几乎与@ 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(a.k.a。Hash#merge!)的形式。当散列{h[:product_id] => h[:price].to_s}(其中harray的元素)被合并到最初为空的散列g时,如果两个散列都包含键h[:product_id]调用块以确定合并散列中该键的值。将三个值传递给块:共享密钥(我没有使用,因此我用占位符_替换了关键的块变量),合并散列中的当前值{ {1}},g(分配给块变量g[:product_id])和要合并的散列值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"}