Ruby do循环分解数组/哈希



我使用has_many :through关系创建了一个自引用数据库:

**Product**
name

**Ingredient**
quantity
product_id
product_component_id

我可以有一个鸡蛋,一盒12个鸡蛋,还有一套16个纸箱。

我试图写一个循环,从一个产品开始,将每个产品的所有组件分解到最基本的状态。目标是退回任何给定产品中的所有基本产品,这样纸箱将退回12个鸡蛋,而平板电脑将退回192个鸡蛋。

我试了一下,这就是我的进展:

def product_breakdown
  results = []
   ingredients.each do |ingredient|
     if ingredient.product_component_id == nil
        results += ingredient
     else
        Keep digging deeper?
     end
   end
  return results
end

当谈到使用循环时,我遗漏了一个完整的概念。如果有人能就这需要的概念的名称提出建议,我将不胜感激。

为了更清楚地编辑我复制的数据库的关系。

class Product < ActiveRecord::Base
    has_many :ingredients 
    has_many :product_components, :through => :ingredients 
end 
class Ingredient < ActiveRecord::Base
    belongs_to :product 
    belongs_to :product_component, class_name: "Product", :foreign_key => "product_component_id" 
end

我建议使用each_with_object来构建数组。这样,您甚至不需要results变量,只需返回each_with_object的返回值即可。

如何区分单元、纸箱和平板?

如果我理解正确,每个成分都有一个component,可以是nilCartonFlat?一个纸箱总是包含12个单元,而一个扁平的16个纸箱?还有一个source,它是一种成分(鸡蛋、牛奶等)

在这种情况下,我将在Ingredient上定义两个助手方法,一个as_unit类方法和一个unit_quantity实例方法:

def unit_quantity
  case product_component_id
  when nil
    quantity
  when CARTON_COMPONENT_ID
    12 * quantity
  when FLAT_COMPONENT_ID
    192 * quantity
  end
end
def self.as_unit ingredients
  source_ids = ingredients.map(&:product_source_id).uniq
  raise "Can't join different types together" if source_ids.count != 1
  source_id = source_ids.first
  quantity = ingredients.reduce(0) { |total, ingredient| total += ingredient.unit_quantity }
  Ingredient.new quantity: quantity, product_component_id: nil, product_source_id: source_id
end

这样,您可以将products_breakdown重写为:

def products_breakdown ingredients
  ingredients.group_by(&:product_source_id).map do |_, ingredients|
    Ingredient.as_unit ingredients
  end
end

这将导致:

$ ingredients
#=> [<Ingredient: 3 Cartons of Egg>, <Ingredient: 2 Flats of Milk>, <17 Units of Egg>]
$ product_breakdown ingredients
#=> [<Ingredient: 53 Units of Egg>, <Ingredient: 384 Units of Milk>]

这就是你想要的吗?我不确定我是否完全理解你的问题。。。

最新更新