Rails组和对象的总和数组

时间:2020-05-18 05:01:29

标签: ruby-on-rails ruby

生产has_many:production_lines, production_line属于:item, has_one项:配方, 配方has_many:recipe_lines, recipe_line归属于:item,

production_linerecipe line具有属性quantity。我需要按生产将配方生产线分组,其数量等于production_line.quantity * recipe_line.quantity

  def item_quantities
        array = production_lines.map do |p|
          p.item.recipe.recipe_lines.map do |r|
            {
              item_id: r.item_id,
              item_name: r.item.name,
              quantity: r.quantity * p.quantity
            }
          end
        end
        array.flatten(1).group_by { |p| p[:item_id] }
             .transform_values { |vals| vals.sum { |val| val[:quantity] } }
          end

这将返回:

item_quantities = {
1: 10,
2: 5
}

其中键是item_id,值是数量。值正确。

但是我想退货:

item_quantities = [
{
id: 1,
name: "Tomato",
quantity: 10,
},
{
id: 2, 
name: "Carrot",
quantity: 5
}
]

我应该如何更改解决方案以实现该目标?

1 个答案:

答案 0 :(得分:4)

首先,可以通过将第一个map放入flat_map来简化嵌套的flatten(1)map的嵌套。如果执行此操作,则可以删除flatten(1)

从这一点来看,您的代码已遍历整个过程,但是您可以进行以下更改以获得所需的输出:

  1. 您可以按多个属性(名称和ID)分组。在另一种语言中,您可以为此使用tuple。 Ruby没有元组,因此我们可以使用len-2数组:

    .group_by { |p| [p[:item_id], p[:item_name]] }
    .transform_values { |vals| vals.sum { |val| val[:quantity] } }
    
  2. 这时,您具有一个将[id,name]元组映射到数量的哈希映射:

    { [1,"foo"] => 123, [2, "bar"] => 456 }
    

    ,您可以使用reduce(如果愿意,可以使用each_with_object)将其强制为所需的数据类型:

    .reduce([]) do |memo, ((id, name), quantity)|
      memo << {
        id: id,
        name: name,
        quantity: quantity
      }
    end
    

看起来((id, name), quantity)奇怪的是一种破坏。具体请参见https://jsarbada.wordpress.com/2019/02/05/destructuring-with-ruby/,有关“解构块参数”和“解构散列”的部分。