Reputation: 852
Here is my collected array.
$raw_ar = Array (
0 => Array ( 'ID' => 6, 'pageTitle' => 'First', 'pageContent' => 'http://localhost/cms/1', 'parentID' => 0 ),
1 => Array ( 'ID' => 7, 'pageTitle' => 'Second', 'pageContent' => 'http://localhost/cms/2', 'parentID' => 6 ),
2 => Array ( 'ID' => 8, 'pageTitle' => 'Third', 'pageContent' => 'http://localhost/cms/3', 'parentID' => 6 ) ,
3 => Array ( 'ID' => 9, 'pageTitle' => 'Four', 'pageContent' => 'http://localhost/cms/4', 'parentID' => 0 )
) ;
And my result should be like this
$final_ar = array(
0 => array ( 'ID' => 6, 'pageTitle' => 'First', 'pageContent' => 'http://localhost/cms/1', 'parentID' => 0 ,
'sub_items' => array(
0 => array('ID' => 7, 'pageTitle' =>'second', 'pageContent' => 'http://localhost/cms/2', 'parentID' => 6),
1 => array('ID' => 8, 'pageTitle' => 'Third', 'pageContent' => 'http://localhost/cms/3', 'parentID' => 6),
)
),
1 => array('ID' => 9, 'pageTitle' => 'Four', 'pageContent' => 'http://localhost/cms/4', 'parentID' => 0)
);
And here is my code
$final_ar = array();
foreach ($raw_ar as $value) {
if($value['parentID'] ==0){
$final_ar[] = $value;
}
else{
$pID = $value['parentID'];
foreach ($final_ar as $value1) {
//echo $value1['ID'].'-'.$pID;
if($value1['ID'] == $pID){
//if(isset($value1['sub_items'])){
$value1['sub_items'][] = $value;
//}else
//$value1['sub_items'] = $value;
}
$temp_ar[] = $value1;
}
$exist = 0;
foreach ($final_ar as $key => $val) {
# code...
if($val['ID'] == $temp_ar['ID']){
unset($final_ar[$key]);
$final_ar[$key] = $temp_ar;
$exist =1;
break;
}
}
if($exist == 0)
$final_arr[] = $temp_ar;
//$parent_key = array_column($raw_ar,'ID', 'parentID');
}
}
print_r($final_arr);
And I tried to code it with sub_items
. But it helps to create array. But I don't know how to remove existing array once it modifies. It gives the result like this.
Array ( [0] => Array ( [0] => Array ( [ID] => 6 [pageTitle] => First [pageContent] => http://localhost/cms/1 [parentID] => 0 [sub_items] => Array ( [0] => Array ( [ID] => 7 [pageTitle] => Second [pageContent] => http://localhost/cms/2 [parentID] => 6 ) ) ) ) [1] => Array ( [0] => Array ( [ID] => 6 [pageTitle] => First [pageContent] => http://localhost/cms/1 [parentID] => 0 [sub_items] => Array ( [0] => Array ( [ID] => 7 [pageTitle] => Second [pageContent] => http://localhost/cms/2 [parentID] => 6 ) ) ) [1] => Array ( [ID] => 6 [pageTitle] => First [pageContent] => http://localhost/cms/1 [parentID] => 0 [sub_items] => Array ( [0] => Array ( [ID] => 8 [pageTitle] => Third [pageContent] => http://localhost/cms/3 [parentID] => 6 ) ) ) ) )
Upvotes: 0
Views: 233
Reputation: 2010
Try this:
function formatArray($nonFormattedArray) {
$formattedArray = [];
$subItems = [];
foreach ($nonFormattedArray as $item) {
$pid = $item['parentID'];
if ($pid != 0) {
if (isset($subItems[$pid]))
$subItems[$pid][] = $item;
else
$subItems[$pid] = [$item];
} else
$formattedArray[] = $item;
}
foreach ($formattedArray as $key => $parent) {
resolveChild($formattedArray[$key], $subItems);
}
return $formattedArray;
}
function resolveChild(&$parent, &$subItems) {
//return if no child
if (!isset($subItems[$parent['ID']]))
return $parent;
foreach ($subItems[$parent['ID']] as $key => $child) {
if (isset($parent['sub_items']))
$parent['sub_items'][] = resolveChild($subItems[$parent['ID']][$key], $subItems);
else
$parent['sub_items'] = [resolveChild($subItems[$parent['ID']][$key], $subItems)];
}
return $parent;
}
Now, formatArray($nonFormattedArray) should return your desired answer.
This will be independent of the order of your parent and child items and will reduce the total iteration count and execution time.
This will produce an Array as deep as the inheritance in the data.
Note that execution time will increase with the increment in inheritance level.
Upvotes: 1
Reputation: 54831
So many code you have here.
Here's my version:
foreach ($raw_ar as $value) {
if ($value['parentID'] == 0) {
$final_ar[$value['ID']] = $value;
}
}
foreach ($raw_ar as $value) {
$parent_id = $value['parentID'];
if (0 < $parent_id) {
if (!isset($final_ar[$parent_id]['sub_items'])) {
$final_ar[$parent_id]['sub_items'] = [];
}
$final_ar[$parent_id]['sub_items'][] = $value;
}
}
$final_ar = array_values($final_ar); // if you need 0-indexed array
If you're 100% sure that parent items in your array come before child ones - you can join both foreach
es into one:
foreach ($raw_ar as $value) {
$parent_id = $value['parentID'];
if ($parent_id == 0) {
$final_ar[$value['ID']] = $value;
} else {
if (!isset($final_ar[$parent_id]['sub_items'])) {
$final_ar[$parent_id]['sub_items'] = [];
}
$final_ar[$parent_id]['sub_items'][] = $value;
}
}
$final_ar = array_values($final_ar); // if you need 0-indexed array
Upvotes: 1