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

问题描述 投票:0回答:1

我正在尝试解决一个问题,我需要计算像“我的三明治”这样的食谱的营养价值

我有一个带有“食谱”和“成分”的数据库,以及千克所需的数量。

食谱可以包含成分,但也包含其他食谱,然后再次可以包含食谱/成分。

这是“测试三明治”的“部件列表”的示例,总重量为0.095千克。

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,
      ),
    ),
  ),
)

如何将这种结构减少到每个“末端”成分的量/重量列表,如面粉,水,香蕉,奶酪,火腿,芝麻等?

我写了这个函数来运行结构,但它并没有真正完成这项工作(似乎正确计算总重量)

function resolveAssembly($items, $number = 1, $declaration = [])
{
    $weight = 0;

    foreach ($items as $item) {
        // Get the quantity (weight) of the item
        $amount = $item['quantity'];

        // Check if the item also contains an ingredients list
        if (array_key_exists('parts', $item)) {

            // Get the total weight of the whole assembly
            list($assembly_weight, $assembly_declaration) = resolveAssembly($item['parts'], $number * $amount, $declaration);

            $declaration = array_merge($declaration, $assembly_declaration);

            // Calculate the relative weight of each part in the assembly
            foreach ($item['parts'] as $part) {
                $weight = $weight + ($amount / $assembly_weight) * $part['quantity'];
            }
        } else {
            // Add the amount to the declaration
            if (!array_key_exists($item['name'], $declaration)) {
                $declaration[$item['name']] =  $number * $amount;
            }

            $weight = $weight + $amount;
        }
    }

    return [$weight, $declaration];
}

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

这就是我使用上述功能的方法:

$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

resolveAssembly()函数的当前结果:

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,所以测试Sesam种子不考虑面包由面粉(面粉,酵母,香蕉等)组成的东西。我想。

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

此外,如果这有帮助,我使用这个系统存储这些食谱:https://github.com/stevebauman/inventory/blob/v1.7/docs/ASSEMBLIES.md(但修改为存储十进制数字和负数(例如处理水丢失或添加做烹饪过程))

这里是为了总结“测试三明治”的总重量而进行的所有计算:

"Test Cheese: 0 + 0.015 = 0.015"

"Test Ham: 0.015 + 0.03 = 0.045"

"Test Flour: 0 + 0.5 = 0.5"

"Test Water: 0.5 + 0.3 = 0.8"

"Test Yeast: 0.8 + 0.05 = 0.85"

"Test Banan: 0.85 + 0.15 = 1"

"Test Flour: 0 + (1 / 1) * 0.5 = 0.5"

"Test Water: 0.5 + (1 / 1) * 0.3 = 0.8"

"Test Yeast: 0.8 + (1 / 1) * 0.05 = 0.85"

"Test Banan: 0.85 + (1 / 1) * 0.15 = 1"

"Test Sesam Seeds: 1 + 0.1 = 1.1"

"Test Bread: 0.045 + (0.05 / 1.1) * 1 = 0.09045454545"

"Test Sesam Seeds: 0.090454545454545 + (0.05 / 1.1) * 0.1 = 0.095"
php weight nested-sets
1个回答
1
投票

这应该让你更接近:

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。

基本上当你做一个“子食谱”时,你需要知道该食谱的总重量是多少,从那里你可以根据该子数量计算实际物品总数。

© www.soinside.com 2019 - 2024. All rights reserved.