Php 如何计算每种成分的含量?

Php 如何计算每种成分的含量?,php,nested-sets,Php,Nested Sets,我试图解决一个问题,我需要计算一个食谱的营养价值,比如“我的三明治” 我有一个数据库,里面有“食谱”和“配料”以及所需的数量(以千克为单位) 配方可以包含配料,也可以包含其他配方,这些配方也可以包含配方/配料 这是总重量为0.095 kg的“试验三明治”的“零件清单”示例 array ( 0 => array ( 'id' => 2, 'name' => 'Test Cheese', 'metric_id' => 1, 'cate

我试图解决一个问题,我需要计算一个食谱的营养价值,比如“我的三明治”

我有一个数据库,里面有“食谱”和“配料”以及所需的数量(以千克为单位)

配方可以包含配料,也可以包含其他配方,这些配方也可以包含配方/配料

这是总重量为0.095 kg的“试验三明治”的“零件清单”示例

array (
  0 => 
  array (
    'id' => 2,
    'name' => 'Test Cheese',
    'metric_id' => 1,
    'category_id' => NULL,
    'quantity' => 0.015,
    'depth' => 1,
  ),
  1 => 
  array (
    'id' => 3,
    'name' => 'Test Ham',
    'metric_id' => 1,
    'category_id' => NULL,
    'quantity' => 0.03,
    'depth' => 1,
  ),
  2 => 
  array (
    'id' => 4,
    'name' => 'Test Sesam Bread',
    'metric_id' => 1,
    'category_id' => NULL,
    'quantity' => 0.05,   // Only use some of the test bread (with added Sesam)
    'depth' => 1,
    'parts' => 
    array (
      0 => 
      array (
        'id' => 5,
        'name' => 'Test Bread',
        'metric_id' => 1,
        'category_id' => NULL,
        'quantity' => 1.0,         // This a recipe for 1 kg of banana bread 
        'depth' => 2,
        'parts' => 
        array (
          0 => 
          array (
            'id' => 6,
            'name' => 'Test Flour',
            'metric_id' => 1,
            'category_id' => NULL,
            'quantity' => 0.5,
            'depth' => 3,
          ),
          1 => 
          array (
            'id' => 7,
            'name' => 'Test Water',
            'metric_id' => 1,
            'category_id' => NULL,
            'quantity' => 0.3,
            'depth' => 3,
          ),
          2 => 
          array (
            'id' => 8,
            'name' => 'Test Yeast',
            'metric_id' => 1,
            'category_id' => NULL,
            'quantity' => 0.05,
            'depth' => 3,
          ),
          3 => 
          array (
            'id' => 9,
            'name' => 'Test Banan',
            'metric_id' => 1,
            'category_id' => NULL,
            'quantity' => 0.15,
            'depth' => 3,
          ),
        ),
      ),
      1 => 
      array (
        'id' => 10,
        'name' => 'Test Sesam Seeds',
        'metric_id' => 1,
        'category_id' => NULL,
        'quantity' => 0.1,
        'depth' => 2,
      ),
    ),
  ),
)
我如何才能将这种结构简化为每个“最终”成分的数量/重量列表,如面粉、水、香蕉、奶酪、火腿、芝麻籽等

我编写这个函数是为了在整个结构中运行,但它并没有真正起作用(似乎它正确地计算了总重量)

编辑:合并程序集声明数组

这是我如何使用上述功能的:

$item = Inventory::findOrFail(1); // Get "Test sandwich"
$parts = $item->getAssemblyItemsList(); // Get the parts of the "Test sandwich"
$result = resolveAssembly($parts, 1); // Get total weight of 1 "Test sandwich" + a list of amount/weight of each ingredient
0.095
[
  "Test Cheese" => 0.015
  "Test Ham" => 0.03
  "Test Flour" => 0.025
  "Test Water" => 0.015
  "Test Yeast" => 0.0025
  "Test Banan" => 0.0075
  "Test Sesam Seeds" => 0.005 // Should have been factored in the bread ingredients
]
resolveAssembly()函数的当前结果:

$item = Inventory::findOrFail(1); // Get "Test sandwich"
$parts = $item->getAssemblyItemsList(); // Get the parts of the "Test sandwich"
$result = resolveAssembly($parts, 1); // Get total weight of 1 "Test sandwich" + a list of amount/weight of each ingredient
0.095
[
  "Test Cheese" => 0.015
  "Test Ham" => 0.03
  "Test Flour" => 0.025
  "Test Water" => 0.015
  "Test Yeast" => 0.0025
  "Test Banan" => 0.0075
  "Test Sesam Seeds" => 0.005 // Should have been factored in the bread ingredients
]
但这并不完全正确,它应该加起来是0.095,所以我认为测试的芝麻籽不包括在面包的成分中(面粉、酵母、香蕉等)

0.015+0.03+0.025+0.015+0.0025+0.0075+0.005=0.1kg“试验三明治”

如果这有帮助的话,我正在使用这个系统来存储这些食谱:(但修改为存储十进制数和负数(例如,处理烹饪过程中丢失或添加的水))

这是所有计算“测试三明治”总重量的总和:


这会让你更接近:

function resolveAssembly($items) {
    $weight = 0;
    $declaration = [];
    foreach ($items as $item) {
        $weight += $item['quantity'];
        if (array_key_exists('parts', $item)) {
            // if there are parts, get the full weight and declaration for the sub item
            list($sub_total_weight, $sub_declaration) = resolveAssembly($item['parts']);
            foreach ($sub_declaration as $sub_name => $sub_weight) {
                if (!array_key_exists($sub_name, $declaration)) {
                    $declaration[$sub_name] = 0;
                }
                // Total weight of particular ingredient is the sub items ingredient out of the sub items full weight
                // times the quantity for this particular item
                $declaration[$sub_name] += $item['quantity'] * ($sub_weight / $sub_total_weight);
            }
        } else {
            // if there are no parts, just add the quantity
            if (!array_key_exists($item['name'], $declaration)) {
                $declaration[$item['name']] = 0;
            }
            $declaration[$item['name']] += $item['quantity'];
        }
    }
    return [$weight, $declaration];
}
这将为您提供以下结果:

array(2) {
    [0]=>
  float(0.095)
  [1]=>
  array(7) {
        ["Test Cheese"]=>
    float(0.015)
    ["Test Ham"]=>
    float(0.03)
    ["Test Flour"]=>
    float(0.022727272727273)
    ["Test Water"]=>
    float(0.013636363636364)
    ["Test Yeast"]=>
    float(0.0022727272727273)
    ["Test Banan"]=>
    float(0.0068181818181818)
    ["Test Sesam Seeds"]=>
    float(0.0045454545454545)
  }
}
如果你把上面的数字加起来,总数应该是0.095


基本上,当你做“子配方”时,你需要知道该配方的总“重量”是多少,从那里,您可以根据sub的数量计算出实际的项目总数。

向我们展示您当前拥有的代码,告诉我们您至少尝试过自己解决这个问题。如果该阵列是带有
var\u export
而不是SteadriggsFolly的打印机,对每个人来说都会容易得多-您是对的,我忘了包括我的功能-它似乎正确地计算了总重量。Andreas-修正(感谢您指出)‘测试芝麻面包’由‘测试面包’和‘测试芝麻籽’组成,这三种(以及任何子部分)是否都应列在配料表中?由于只使用了“测试Sesam面包”的一部分,是否需要将其分解到其子部分中?@inckie如果您可以发布您对结果的预期,这将是有帮助的,他们应该在哪里添加这一点?它有什么作用?为您的答案提供一些上下文。合并它是否正确?因为正如你所说的,如果集合声明中的一个成分已经存在于声明中,那么它必须被添加(我猜),它似乎是“数量”和“重量”的混合体。例如,它要求0.05的“测试芝麻面包”,但是“测试芝麻面包”的两部分加起来是和否分别为1.1“kg。我这样认为:你不烤一条面包,你烤一个1 kg的完整面包,然后在面包中添加0.1 kg(100 g)的芝麻籽,以创建另一种面包变体。然后你切一块重量为0.05公斤(50克)的面包来做三明治。非常感谢-我根据真实的配方数据验证了该函数,它返回的结果与目前用于进行这些计算的已有25年历史的旧delphi程序相同。