Jack Jack - 3 months ago 8
PHP Question

php build strings from array elements

I`ve got the following array:

$myarray = array
(
2 => array
(
'id' => '2',
'parent_id' => '1',
),
4 => array
(
'id' => '4',
'parent_id' => '2',
),
3 => array
(
'id' => '3',
'parent_id' => '1',
),
1 => array
(
'id' => '1',
'parent_id' => '0',
)
);


and the goal is to have the following output:

1
1.2
1.2.4
1.3


The problem is that I need to do that without recursion. Here is some kind of an answer but the guys there are building tree while I need to have strings. I tried to use some kind of $basestring variable in order to know where am I, but still it did not work without recursion. Any ideas how to do that?

Thank you

UPD My first attempt was the following:

foreach($myarray as $k=>$value){
if($value['parent_id'] == 0){
$string = '1';
$id = $value['id'];
$newarr[0] = $string;
$basestring = $string.'.';
}elseif($value['parent_id'] == 1){
$string = $basestring.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}elseif($value['one'] == 2){
$string = $basestring.$value['parent_id'].'.'.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}elseif($value['parent_id'] == 3){
$string = $basestring.$value['parent_id'].'.'.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}elseif($value['parent_id'] == 4){
$string = $basestring.$value['parent_id'].'.'.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}//etc...
}
}


but obviously it failed due to non-scalability. I need to code somehow the iteration from child to parent here

Answer

An iterative solution could work something like this:

foreach ($myarray as $x) {
    $temp = $x;
    $string = [];

    while (true) {
        $string[] = $temp['id'];                            // add current level id
        if (!isset($myarray[$temp['parent_id']])) break;    // break if no more parents
        $temp = $myarray[$temp['parent_id']];               // replace temp with parent
    }

    $strings[] = implode('.', array_reverse($string));
    // array_reverse is needed because you've added the levels from bottom to top
}

Basically for each element of the array, create a temporary copy, then find its parents by key and set the temporary copy to the parent until no more parents are found. Add the ids into an array as you go and build the string from the array when you get to the end.

This assumes your array is valid, in that it does not contain circular references (e.g. one level being its own ancestor). To prevent an infinite loop if this did happen, you could increment a variable within the while loop and break if it reached some reasonable limit.