如何计算每种成分的用量?
How to calculate the amount of each ingredient?
我正在尝试解决一个问题,我需要计算 "My sandwich"
等食谱的营养价值
我有一个包含 "recipes" 和 "ingredients" 的数据库以及以公斤为单位的所需数量。
一个食谱可以包含配料,但也可以包含其他食谱,然后又可以包含 recipes/ingredients。
这是一个 "part list" 的 "Test Sandwich" 的例子,总重量为 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,
),
),
),
)
我怎样才能将这样的结构缩减为每个 "end" 成分的 amount/weight 列表,例如面粉、水、香蕉、奶酪、火腿、芝麻等?
我通过结构将这个函数写到运行,但它并没有真正完成工作(似乎它正确计算了总重量)
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,所以我认为测试芝麻不在面包的成分(面粉、酵母、香蕉等)中。
0.015+0.03+0.025+0.015+0.0025+0.0075+0.005 = 0.1 公斤 "Test Sandwich"
此外,如果这有帮助,我正在使用这个系统来存储这些食谱:https://github.com/stevebauman/inventory/blob/v1.7/docs/ASSEMBLIES.md(但经过修改以存储十进制数和负数(例如处理在烹饪过程中丢失或添加的水) )
这里是对 "Test Sandwich" 的总重量求和的所有计算:
"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"
这会让你们更接近:
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 recipe' 时,你需要知道那个食谱的总数 'weight' 是多少,然后你可以根据那个子的数量计算出实际的物品总数.
我正在尝试解决一个问题,我需要计算 "My sandwich"
等食谱的营养价值我有一个包含 "recipes" 和 "ingredients" 的数据库以及以公斤为单位的所需数量。
一个食谱可以包含配料,但也可以包含其他食谱,然后又可以包含 recipes/ingredients。
这是一个 "part list" 的 "Test Sandwich" 的例子,总重量为 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,
),
),
),
)
我怎样才能将这样的结构缩减为每个 "end" 成分的 amount/weight 列表,例如面粉、水、香蕉、奶酪、火腿、芝麻等?
我通过结构将这个函数写到运行,但它并没有真正完成工作(似乎它正确计算了总重量)
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,所以我认为测试芝麻不在面包的成分(面粉、酵母、香蕉等)中。
0.015+0.03+0.025+0.015+0.0025+0.0075+0.005 = 0.1 公斤 "Test Sandwich"
此外,如果这有帮助,我正在使用这个系统来存储这些食谱:https://github.com/stevebauman/inventory/blob/v1.7/docs/ASSEMBLIES.md(但经过修改以存储十进制数和负数(例如处理在烹饪过程中丢失或添加的水) )
这里是对 "Test Sandwich" 的总重量求和的所有计算:
"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"
这会让你们更接近:
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 recipe' 时,你需要知道那个食谱的总数 'weight' 是多少,然后你可以根据那个子的数量计算出实际的物品总数.