Как в цикле суммировать найденные значения верхнему уровню?

У меня есть категории, которые имеют/не имеют дочерние категории. Также есть товары, которые принадлежат одной или нескольким категориям.

Мне нужно посчитать количество товаров у всех родительских категориях, включаю дочерние.

Я получаю такой php-массив, где ключ массива это ID категории, а в значении массива указано ID родителя, ID в базе и количество товаров конечной категории:

array (size=1505)
  1 => 
    array (size=3)
      'id' => int 30
      'parent_id' => null
      'count' => int 0
  2 => 
    array (size=3)
      'id' => int 31
      'parent_id' => null
      'count' => int 0
  21 => 
    array (size=3)
      'id' => int 32
      'parent_id' => int 2
      'count' => int 0
  211 => 
    array (size=3)
      'id' => int 33
      'parent_id' => int 21
      'count' => int 5689
  212 => 
    array (size=3)
      'id' => int 34
      'parent_id' => int 21
      'count' => int 1547
  //...

Вот таким методом я получаю дочерние элементы только первого уровня. А мне нужно получить все дочерние категории.

foreach($tree as $id => $item) {
   if ($item['parent_id'] !== null) {
      $parent_id = $item['parent_id'];
      $tree[$parent_id]['childs'][] = $id;
   }
}

Каким образом я могу в родительской категории просуммировать количество товаров всех дочерних категорий?

Понятно, что нужно использовать цикл, но каким образом я не пойму :с


Ответы (1 шт):

Автор решения: Vladimir Ignatenko

Не совсем понятна логика данного массива. parent_id это значение ключа с элементом или же надо искать по id элемента. Логичнее было бы чтобы id 'элемента был бы ключом в данном массиве.

И тогда если есть уверенность, что в массиве сначала идут элементы верхнего уровня, а потом уже дочерние, то можно попробовать пройти массив с конца к началу и просто посчитать сумму как

$arr[$item['parent_id']]['count']+= $item['count'];

Т.е. для каждого элемента $item находим в основном массиве $arr его родительский элемент и прибавляем к сумме число из текущего элемента.

Если уверености в сортировке нет, то можно один раз пройти весь массив и сформировать для каждого элемента список id его дочерних элементов.

Как-то так

foreach($arr as $id => $item) {
  $parent_id = $item['parent_id'];
  if (!isset($arr[$parent_id]['childs']) {
     $arr[$parent_id]['childs'] = [];
  }
  $art[$patent_id]'childs'][] = $id;
}

А дальше уже с помощью массива childs можно пройти по всем элементам и посчитать суммы.

→ Ссылка