Viewed   90 times

I have some data in this format:

one,one
two,two
sub_one,one
sub_two,two
sub_sub_one,sub_one
sub_sub_two,sub_two
sub_sub_sub_one,sub_sub_one
sub_sub_sub_two,sub_sub_two

Now I want to create nested arrays that contains that data, I coded this:

<?php
$lines[] = "one,one";
$lines[] = "two,two";
$lines[] = "sub_one,one";
$lines[] = "sub_two,two";
$lines[] = "sub_sub_one,sub_one";
$lines[] = "sub_sub_two,sub_two";
$lines[] = "sub_sub_sub_one,sub_sub_one";
$lines[] = "sub_sub_sub_two,sub_sub_two";

foreach($lines as $line)
{
    $tmp = explode(",", $line);
    $array[$tmp[1]][$tmp[0]] = $tmp[0];
}

foreach($array as $key => $value)
{
    foreach($array[$key] as $value2)
    {
        if(array_key_exists($value2, $array) && $value2 != $key)
        {           
            $array[$key][$value2] = $array[$value2];
            $unset[] = $value2;
        }
        else
        {
            unset($array[$key]);
        }
    }
}

foreach($unset as $un)
{
    unset($array[$un]);
}

print_r($array);
?>

But this only goes down to the 3rd level and no futher. The output looks like this:

Array
(
    [one] => Array
        (
            [sub_one] => Array
                (
                    [sub_sub_one] => sub_sub_one
                )

        )

    [two] => Array
        (
            [sub_two] => Array
                (
                    [sub_sub_two] => sub_sub_two
                )

        )

)

sub_sub_sub_one and sub_sub_sub_two are not in the output, how can I make my code recursive so no matter how many levels or relation exists in the data it will still work?

 Answers

4

Hmm from your code I understand that "one,one" means "one" is at top-level, and otherwise "a,b" means "a" is child of "b".

You could just convert all links into an associative array format, such that $links['a'] = 'sub_a' if sub_a is a child of 'a'. Then populate $nested recursively with the children of its deeper and deeper keys.

A sample code follows:

<?php

$nested = array();
$links = array();

// first, create a structure that contains the connections between elements
foreach ($lines as $line) {
  list($child, $parent) = explode(",", $line);
  if ($child == $parent) {
    $nested[$parent] = null;
  } else {
    // add it to the children of parent
    $links[$parent][] = $child;
  }
}

function process(&$arr) {
  global $links;
  foreach ($arr as $key => $value) {
    // no more children => stop recursion
    if (!array_key_exists($key, $links)) {
      $array[$key] = null;
      continue;
    }
    // insert its children
    $arr[$key] = array_flip($links[$key]);
    // recurse down
    process($arr[$key]);
  }
}

process($nested);

// $nested contains your m-dim array
print_r($nested);

?>

And the output:

Array
(
    [one] => Array
        (
            [sub_one] => Array
                (
                    [sub_sub_one] => Array
                        (
                            [sub_sub_sub_one] => 
                        )

                )

        )

    [two] => Array
        (
            [sub_two] => Array
                (
                    [sub_sub_two] => Array
                        (
                            [sub_sub_sub_two] => 
                        )

                )

        )

)
Monday, November 21, 2022
 
ridoy
 
5
$x = count($array) - 1;
$temp = array();
for($i = $x; $i >= 0; $i--)
{
    $temp = array($array[$i] => $temp);
}
Monday, December 5, 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
 
4

You can try something like this and can modify it as per your requirement

for($i=0;$i<count($arr);$i++){

    if( $arr[$i]['parent_id'] == null ){
        $data[] = array(
            'id' => $arr[$i]['id'],
            'Name' => $arr[$i]['name'],
            'sub' => array()
        );
    }elseif( $arr[$i]['parent_id'] != null){
        for($j=0;$j<count($data);$j++){
            if( $data[$j]['id'] == $arr[$i]['parent_id'] ){
                $data[$j]['sub'][] = createChild($arr[$i]); 
            }else{
                for($k=0;$k<count($data[$j]['sub']);$k++){
                    if($data[$j]['sub'][$k]['id'] == $arr[$i]['parent_id']){
                        $data[$j]['sub'][$k]['sub'] = createChild($arr[$i]);    
                    }
                }
            }
        }
    }
}

function createChild($obj){
    return array(
        'id' => $obj['id'],
        'name' => $obj['name'],
        'parent_id' => $obj['parent_id'],
        'sub' => array()
    );
}
Sunday, August 7, 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 :