3

I have blackhole in my mind. Im trying to parse array with multilevel nodes. Here's example array:

global $array;
$array = [
 '0' => [
 'id' => 1,
 'parent' => 0,
 'name' => 'root 0'
 ],
 '1' => [
 'id' => 2,
 'parent' => 1,
 'name' => 'root 1'
 ],
 '2' => [
 'id' => 3,
 'parent' => 2,
 'name' => 'root 2'
 ],
 '3' => [
 'id' => 4,
 'parent' => 3,
 'name' => 'root 3'
 ],
 '4' => [
 'id' => 5,
 'parent' => 3,
 'name' => 'root 4'
 ],
 '5' => [
 'id' => 6,
 'parent' => 2,
 'name' => 'root 2'
 ]
];

This should looks after parse like this. Element 3 with parent 3 should have parent 1, because element 2 has parent 2, and its first child.

I trying to get to this using foreach and function:

global $new_array;
$new_array = [];
foreach( $array as $item )
{
 if( $item['parent'] == 0 ) {
 $new_array[] = $item; // if parent 0 - clone into new array
 continue;
 }
 //echo $item['name'] . PHP_EOL;
 $new_array[] = check_parent( $item['parent'] ); 
}
print_r($new_array);
function check_parent( $parent )
{
 //echo '- check for parent of ' . $parent . PHP_EOL;
 global $array;
 foreach( $array as $item ) {
 if( $item['id'] == $parent && $item['parent'] == 0 ) {
 //echo '[OK] found root parent id: ' . $item['id'] . PHP_EOL;
 $item['parent'] = $item['id'];
 return $item;
 } else {
 return check_parent( $item['id'] );
 }
 }
}

I'm so confused, but I didn't see where I make a mistake. Maybe someone, can help me to see - where's problem. I working on it few hours and for now, I had blackhole in my mind.

Fiddle: https://implode.io/jHS8m1

Desired output:

$new_array = [
 '0' => [
 'id' => 1,
 'parent' => 0,
 'name' => 'root 0'
 ],
 '1' => [
 'id' => 2,
 'parent' => 1,
 'name' => 'root 1'
 ],
 '2' => [
 'id' => 3,
 'parent' => 2, // this should have after parse parent 1
 'name' => 'root 2'
 ],
 '3' => [
 'id' => 4,
 'parent' => 3, // this should have after parse parent 1
 'name' => 'root 3'
 ],
 '4' => [
 'id' => 5,
 'parent' => 3, // this should have after parse parent 1
 'name' => 'root 4'
 ],
 '5' => [
 'id' => 6,
 'parent' => 2, // this should have after parse parent 1
 'name' => 'root 2'
 ]
];

Thanks !

asked Oct 1, 2019 at 9:39
1
  • You are right. This is what I need to do. This is n-version of this script, some time ago I wrote something similar without any problems, but now - its like i don't know what i'am doing - so I ask for help, because after few hours I stuck and have no idea how to make this happen. This script doesn't had replace for grandparent, but if returns correct values, replace parent will be a easy. Commented Oct 1, 2019 at 9:55

2 Answers 2

1

Replace the following line in your code

 $new_array[] = check_parent( $item['parent'] ); // get child

with below lines of code.

 $temp = check_parent( $item['parent'] ); // get child
 $item['parent'] = $temp['id'];
 $new_array[] = $item;

What is happening is that your check_parent is returning the $item, which happens to be the parent. However, we are only interested in the id of this. So we get the id and replace the parent it in the original $item.

Here is the working Demo

answered Oct 1, 2019 at 10:01
0
0

A bit tardy in my response, but I think it is valuable to provide a refined recursive solution.

My snippet:

  1. Modifies by reference
  2. Does not leverage a global variable declaration
  3. Uses just one loop in the custom recursive function.

Code: (Demo)

function replaceParent(&$array, $parent = null) {
 foreach ($array as &$item) {
 if ($item['id'] == $parent) {
 if ($item['parent']) {
 return replaceParent($array, $item['parent']);
 } else {
 return $item['id'];
 }
 } elseif ($item['parent']) {
 $item['parent'] = replaceParent($array, $item['parent']);
 }
 }
}
replaceParent($array);
var_export($array);

I'll try to explain...

  • id 1's parent value of 0 fails both primary conditions, so no recursion/processing is performed on that row of data.

  • id 2's parent value of 1 passes the elseif condition, so the recursive call goes in search of the row with an id of 1. Finding id 1 with a parent value of 0 means the else branch is satisfied and the id value of 1 is passed back through the recursive call to be assigned to $item['parent'] for the original id 2.

  • To process id 3 (or deeper), multiple recursive calls occur and all conditions play a role in the search and assignment process. First the elseif leads to the first recursion, then the if's if leads to the second recursion, finally the if's else passes the root id's value all the way back to the original grandchild.

answered Oct 5, 2019 at 12:36

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.