Bene Bene - 5 months ago 11
PHP Question

Sort array of categories by root category first

I would like sort a given array of categories. The root categories must appear first before their child categories in a new array.

Example data:

$data = [
['id' => '1', 'name' => 'abc', 'parent_id' => '0' ],
['id' => '4', 'name' => 'def', 'parent_id' => '5' ],
['id' => '3', 'name' => 'ghj', 'parent_id' => '2' ],
['id' => '5', 'name' => 'zst', 'parent_id' => '1' ],
['id' => '2', 'name' => 'klm', 'parent_id' => '1' ],
];


Output I would like to achieve:

$output = [
'1' => ['id' => '1', 'name' => 'abc', 'parent_id' => '0' ],
'5' => ['id' => '5', 'name' => 'zst', 'parent_id' => '1' ],
'4' => ['id' => '4', 'name' => 'def', 'parent_id' => '5' ],
'2' => ['id' => '2', 'name' => 'klm', 'parent_id' => '1' ],
'3' => ['id' => '3', 'name' => 'ghj', 'parent_id' => '2' ],
];


My code until now:

function sortCategories($data) {
$output = [];
foreach ($data as $category) {
if ($output[$category['id']] || $output[$category['parent_id']])
continue;

if (!$output[$category['parent_id']])
$output = getParentCategories($category, $ouput, $data);

$output[$category['id']] = [
'id' => $category['id'],
'name' => $category['name'],
'parent_id' => $category['parent_id']
];
}
return $output;
}

function getParentCategories($category, $output, $data) {
if ($output[$category['parent_id']]) {
return $output;
} else {
}
}


The problem I have is that I don't know how to probably implement getParentCategories() so that this function handles root categories the right way.

Any suggestions how to solve the problem?

Answer

A solution using foreach() will work for you:-

<?php 
$data = [
  ['id' => '1', 'name' => 'abc', 'parent_id' => '0' ],
  ['id' => '4', 'name' => 'def', 'parent_id' => '5' ],
  ['id' => '3', 'name' => 'ghj', 'parent_id' => '2' ],
  ['id' => '5', 'name' => 'zst', 'parent_id' => '1' ],
  ['id' => '2', 'name' => 'klm', 'parent_id' => '1' ],
]; // original array

$new_array = array(); // new empty array

foreach($data as $key=>$value){ // iterate through original array
    if($value['parent_id'] == 0){ // check root value
        $new_array[$value['id']] = $value; // assign full sub-array to newly created array
    }else{ // if not root value
        $get_key = searchForId($value['parent_id'],$data); // based on parent-id get the parent array key from original array
            $new_array[$data[$get_key]['id']] = $data[$get_key]; // based on key assign parent array to the newly created array
            $new_array[$value['id']] = $value; // assign the child array to newly created array
    }

}
function searchForId($id, $array) { // send parent_id and original array
   foreach ($array as $key => $val) {
       if ($val['id'] === $id) {
           return $key; // return key of parent id
       }
   }
   return null;
}
echo "<pre/>";print_r($new_array); // print new array
?>

Output:- https://eval.in/599837

Comments