我有一个“食品食谱”,其中用于制作食谱的所有子成分都在树中构成
我早些时候获得了一些帮助,以创建一些代码来使树变平并计算每种基本成分(叶)的重量:How to calculate the amount of each ingredient?
但是现在我也想跟踪每种成分的制备方法(但仍要总结成分的重量)。
为此,我向每个节点添加了一个称为“准备”的额外属性
但是我很难弄清如何跟踪整个准备链。
以下是配方树结构的示例:
$tree = [
[
'name' => 'a',
'weight' => 1,
'preparation' => 'boiled',
'tree' => [
[
'name' => 'c',
'weight' => 3,
'preparation' => 'baked',
],
[
'name' => 'c',
'weight' => 3,
'preparation' => 'fried',
],
]
],
[
'name' => 'b',
'weight' => 1,
'preparation' => 'boiled',
'tree' => [
[
'name' => 'd',
'weight' => 4,
'preparation' => 'none',
'tree' => [
[
'name' => 'e',
'weight' => 1,
'preparation' => 'fried',
],
[
'name' => 'f',
'weight' => 1,
'preparation' => 'none',
]
]
],
[
'name' => 'c',
'weight' => 1,
'preparation' => 'baked', // b[1]c has the same "preperation chain" as a[0]c
]
]
],
[
'name' => 'c',
'weight' => 1,
'preparation' => 'none',
]
];
我希望将其减少为每个“基本成分重量”(叶)和制备链(路径)的阵列。
array (
'c-baked,boiled' => 0.7,
'c-fried,boiled' => 0.5,
'e-fried,none,boiled' => 0.4,
'f-none,none,boiled' => 0.4,
'c-none' => 1,
)
出于争论的目的,在不考虑准备的情况下,结果如下所示:
array (
'c' => 2.2, // 0.7 + 0.5 + 1
'e' => 0.4,
'f' => 0.4,
)
我只能获得跟踪基本成分(叶)而不是完整链的制备的代码:
array (
'c-baked,boiled' => 0.2,
'c-fried,boiled' => 0.5,
'e-fried,none,boiled' => 0.4,
'f-none,none,boiled' => 0.4,
'c-none' => 1,
)
这是代码的外观:
//function getBaseIngredients(array $tree): array
function getBaseIngredients(array $tree, $preparation = null): array
{
$leafs = [];
// Loop through the nodes in the tree if the node
// is a leaf we sum the weight, otherwise we recursivly
// call our self and resolve the branch
foreach($tree as $node){
if(empty($node['tree']))
{
// if there are no parts, just add the weight
//$key = $node['name'] . '-' . $node['preparation'];
$key = $node['name'] . '-' . $node['preparation'] . $preparation;
if(!array_key_exists($node['name'], $leafs)) {
$leafs[$key] = 0;
}
$leafs[$key] += $node['weight'];
} else {
// if there sub nodes, get the full weight node
$nodes = getBaseIngredients($node['tree'], $preparation);
$total = array_sum($nodes);
// Scale each sub node according to the parent
foreach($nodes as $key => $weight){
if(!array_key_exists($key, $leafs)) {
//$leafs[$key] = 0;
$leafs[$key . ',' . $node['preparation']] = 0;
}
// Total weight of particular node is the
// sub node out of the sub node full weight
// times the weight for this particular leaf
// $leafs[$key] += $node['weight'] * ($weight / $total);
$leafs[$key . ',' . $node['preparation']] += $node['weight'] * ($weight / $total);
}
}
}
return $leafs;
}