У меня есть «рецепт еды», в котором все вспомогательные ингредиенты, которые используются для приготовления рецепта, структурированы в виде дерева.
. Ранее я получил некоторую помощь в создании некоторого кода для выравнивания дерева и вычисленияВес каждого базового ингредиента (листа): Как рассчитать количество каждого ингредиента?
Но теперь я также хочу отследить, как готовится каждый ингредиент (но все же суммирую вес ингредиентов).
Я добавил для каждого узла дополнительный атрибут, называемый «подготовка»
, но я пытаюсь выяснить, как я могу отслеживать всю цепочку подготовки.
Вот пример структуры дерева рецептов:
$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,
)
Мне удалось получить только код для отслеживания подготовки of базовый ингредиент (лист), а не полная цепочка:
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;
}