Viewed   73 times

I have an array in php with Objects containing an id and a parent_id. All Objects without a parent_id should be the root Objects in a new array.

All Objects that do have a parent_id should be pushed in the correct Object's children array:

So this is my original array:

array
  0 => 
    object(Node)[528]
      protected 'id' => int 1
      protected 'parent_id' => null
  1 =>
   object(Node)[529]
      protected 'id' => int 2
      protected 'parent_id' => null
  2 => 
   object(Node)[530]
      protected 'id' => int 3
      protected 'parent_id' => 1
  3 =>  
   object(Node)[531]
      protected 'id' => int 4
      protected 'parent_id' => 1
  4 =>  
  object(Node)[532]
      protected 'id' => int 5
      protected 'parent_id' => 4
  5 =>  
  object(Node)[533]
      protected 'id' => int 6
      protected 'parent_id' => 4

this is what the new array should look like:

$nodes = array(
  array(
   'id' => 1,
   'parent_id' => null,
   'children' => array(
    array(
     'id' => 3,
     'parent_id' => 1,
     'children' => null
    ),
    array(
     'id' => 4,
     'parent_id' => 1,
     'children' => array(
      array(
       'id' => 5,
       'parent_id' => 4
      ),
      array(
       'id' => 6,
       'parent_id' => 5
      ), 
     )
    ),
   ),
  ),
  array(
   'id' => 2,
   'parent_id' => null,
   'children' => null
  ),
 );

Any Idea how I could do this?

 Answers

4

Try something like this:

// collects all nodes that belong to a certain parent id
function findChildren($nodeList, $parentId = null) {
    $nodes = array();

    foreach ($nodeList as $node) {
        if ($node['parent_id'] == $parentId) {
            $node['children'] = findChildren($nodeList, $node['id']);
            $nodes[] = $node;
        }
    }

    return $nodes;
}

Use it like this:

$nestedNodes = findChildren($nodeList);

This code recursively searches for the given parent_id in the original $nodeList. If a matching node is found, it searches for the children of this node, and so on. If no children for the given parent_id are found, an empty array is retuned.

You could reduce the memory usage of this approach by using references for $nodeList.

Saturday, October 1, 2022
 
4

You need to iterate over your results, adding a new entry to the output when you encounter a new team, or updating the points value when you find the same team again. This is most easily done by initially indexing the output by the team name, and then using array_values to re-index the array numerically:

$teams = array();
foreach ($results as $result) {
    $team = $result['team'];
    if (!isset($teams[$team])) {
        $teams[$team] = array('team' => $team, 'points' => $result['punti']);
    }
    else {
        $teams[$team]['points'] += $result['punti'];
    }
}
$teams = array_values($teams);
print_r($teams);

Output (for your sample data):

Array
(
    [0] => Array
        (
            [team] => Red Bull Racing
            [points] => 418
        )
    [1] => Array
        (
            [team] => Scuderia Ferrari
            [points] => 353
        )
    [2] => Array
        (
            [team] => Mercedes-AMG
            [points] => 516
        )
    [3] => Array
        (
            [team] => Racing Point F1
            [points] => 147
        )
    [4] => Array
        (
            [team] => Haas F1
            [points] => 127
        )
)

Demo on 3v4l.org

Friday, August 12, 2022
 
1

First use array_filter() to get rid of the   nodes:

$array = array_filter($array, function($x) { return trim($x) != ' '; });

// Or if your PHP is older than 5.3
$array = array_filter($array, create_function('$x', 'return trim($x) != " ";'));

Then use array_chunk() to split the array into chunks of 3:

$array = array_chunk($array, 3);

This of course assumes you will always and only get tuples containing name, value and size, in that order.

Wednesday, December 7, 2022
 
5

This is the code you may want where $array = to the array you specified above.

$newArray = [];

foreach($array as $segment) {
    foreach($segment as $key => $value) {
        $newArray[$key] = $value;
    }
}

print_r($newArray);

This is the output:

Array
(
    [textkey] => text
    [file] => file2.xml
    [anotherkey] => another text
    [text_success] => Success
    [newfile] => scope.txt
)

But, there is a problem. Both the file keys are not shown, because a single key cannot be used multiple times in an array. To get over that issue, you can assign a simple array to the file key with the file names like this:

$newArray = [];

foreach($array as $segment) {
    foreach($segment as $key => $value) {
        if($key == 'file') {
            $newArray['file'][] = $value;   
        } else {
            $newArray[$key] = $value;
        }
    }
}

print_r($newArray);

This gives the output:

Array
(
    [textkey] => text
    [file] => Array
        (
            [0] => file.txt
            [1] => file2.xml
        )

    [anotherkey] => another text
    [text_success] => Success
    [newfile] => scope.txt
)
Friday, December 23, 2022
 
3

You can do it like this, do the calculation from the innermost of the array. Check the demo.

<?php
function f(&$array)
{
    foreach($array as $k => &$v)
    {
        if(is_array($v))
        {
            if(count($v) == count($v, 1))
            {
                unset($array[$k]);
                if($k == 'sum')
                {
                    $v =  array_sum($v);
                    $array[] = $v;

                }elseif($k == 'multiply'){
                    $v = array_product($v);
                    $array[] = $v;
                }else{

                    foreach($v as $vv)
                        $array[] = $vv;
                }
            }else
                f($v);
        }
    }
}

while(count($array) != count($array, 1))
{
    f($array);
}

print_r($array);

Note:

traverse array from outer to inner
traverse array from inner to outer

Monday, November 14, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :