Count number of leaves in nested array tree

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-10 17:34:57

问题


I have a nested array tree, generated from a flat array with the following function :

function convertToTree(array $flat, $idField = 'id',
                        $parentIdField = 'parentId',
                        $childNodesField = 'childNodes') {
    $indexed = array();
    // first pass - get the array indexed by the primary id  
    foreach ($flat as $row) {
        $indexed[$row[$idField]] = $row;
        $indexed[$row[$idField]][$childNodesField] = array();
    }

    //second pass  
    $root = null;
    foreach ($indexed as $id => $row) {
        $indexed[$row[$parentIdField]][$childNodesField][$id] =& $indexed[$id];
        if (!$row[$parentIdField]) {
            $root = $id;
        }

    }
    return array($root => $indexed[$root]);
}

I would need to add an entry "NUMBER OF LEAVES" for each node of my array. This entry should count ALL the leaves of all the subnodes of the node :

Array ( 
    [9] => Array ( 
        [id] => 9, 
        [parentId] => null,
        [name] => Item 0, 
        [NUMBER OF LEAVES] => 4,  (corresponding to leaves 100 and 101 + 200 and 201)
        [childNodes] => Array 
            ( 
                [1] => Array ( 
                    [id] => 1, 
                    [parentId] => 9, 
                    [name] => Item 1, 
                    [NUMBER OF LEAVES] => 2,   (corresponding to leaves 100 and 101)
                    [childNodes] => Array ( 
                        [10] => Array ( 
                            [id] => 10, 
                            [parentId] => 1, 
                            [name] => Item 10, 
                            [childNodes] => Array ( 
                                [100] => Array ( 
                                    [id] => 100, 
                                    [parentId] => 10, 
                                    [name] => Item 100, 
                                    [childNodes] => Array ( ) 
                                ) 
                                [101] => Array ( 
                                    [id] => 101, 
                                    [parentId] => 10, 
                                    [name] => Item 101, 
                                    [childNodes] => Array ( ) 
                                ) 
                            ) 
                        ) 
                    ) 
                ) 
                [2] => Array ( 
                    [id] => 2, 
                    [parentId] => 9, 
                    [name] => Item 2, 
                    [NUMBER OF LEAVES] => 2,   (corresponding to leaves 200 and 201)
                    [childNodes] => Array ( 
                        [20] => Array ( 
                            [id] => 20, 
                            [parentId] => 2, 
                            [name] => Item 20, 
                            [childNodes] => Array ( 
                                [200] => Array ( 
                                    [id] => 200, 
                                    [parentId] => 20, 
                                    [name] => Item 200, 
                                    [childNodes] => Array ( ) 
                                ) 
                                [201] => Array ( 
                                    [id] => 201, 
                                    [parentId] => 20, 
                                    [name] => Item 201, 
                                    [childNodes] => Array ( ) 
                                ) 
                            ) 
                        ) 
                    ) 
                ) 
            ) 
    ) 
)

回答1:


this could solve your problem of "NUMBER OF LEAVES" for each node of my array. This entry should count ALL the leaves of all the subnodes of the node"

its from php manual `$food = array('fruits' => array('orange', 'banana', 'apple'), 'veggie' => array('carrot', 'collard', 'pea'));

     // recursive count
     echo count($food, COUNT_RECURSIVE); // output 8

     // normal count
     echo count($food); // output 2`



回答2:


You can do it easily as :

$leaves = 0;
array_walk_recursive($yourArray, function ($leaves) use (&$leaves) {
  $leaves++;
});

Example :

$foods = array(
  'fruits' => array('orange', 'banana', 'apple'),
  'veggie' => array('carrot', 'collard', 'pea')
);

$leaves = 0;
array_walk_recursive($foods, function ($leaves) use (&$leaves) {
  $leaves++;
});
echo $leaves; // will output 6



回答3:


The way to solve this problem is using array_walk_recursive.

Example:

new LeaveCounter();

class LeaveCounter
  {
  public function __construct()
    {
    $this->sweet = array('a' => 'apple', 'b' => 'banana');
    $this->fruits = array('sweet' => $this->sweet, 'sour' => 'lemon');

    $this->leaves = 0;

    array_walk_recursive($this->fruits, 'LeaveCounter::incrementLeaves');

    echo $this->leaves;
    }

  public function incrementLeaves($item, $key)
    {
    $this->leaves += 1;
    }
  }

This counts apple, banana and lemon, so it returns 3.




回答4:


//find Totalaleaves
$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($array),
    RecursiveIteratorIterator::SELF_FIRST
);

$ti = 0;
// NUMBER OF LEAVES keys
$tcount = 0;
// NUMBER OF LEAVES values
foreach ($iterator as $key => $item) {
    if (is_array($item) && $item['NUMBER OF LEAVES'] > 0) {
        $tcount = $tcount + $item['NUMBER OF LEAVES'];
        $ti++;
    }
}

echo "Totalleaveskeys=" . $ti;
echo "Totalleavesvalues=" . $tcount;

This solution work for the unlimited nested multidimensional arrays



来源:https://stackoverflow.com/questions/17293354/count-number-of-leaves-in-nested-array-tree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!