Reputation: 630
I need help with my array. For several hours trying to find a solution but I can not cope. I tried to do it in such a way, however, the code turned out to be completely useless.
private function findKey($array, $keySearch,$app,$klucz='')
{
foreach ($array as $key => $item) {
if ($key == $keySearch) {
$c2 = [];
$cache = [
'nazwa'=>$app->nazwa,
'link'=>$app->link,
'child'=>[]
];
// echo $klucz; echo '<br />';
if($klucz && $klucz != '/'){
// echo $klucz;
// $k = explode('/',$klucz);
// $url = "/2/22/";
// debug($klucz);
$parts = explode('/',$klucz);
debug($klucz);
debug($parts);
$x = 0;
$last = $parts[count($parts)-1];
$arr = array();
while ($bottom = array_pop($parts)) {
if($bottom != $last){
$arr = array($bottom => $arr);
$x++;
}else{
array_push($arr, $cache);
}
}
// $arr['child'] = $cache;
debug($arr);
// exit;
// print_r($output);
// exit;
// self::buildKey($k);
// print_r($c2);
echo "<br />";
}
}
else {
$klucz = $klucz.'/'.$key;
if (is_array($item) && self::findKey($item, $keySearch,$app,$klucz)) {
// return true;
}
}
}
// return false;
}
I need to create array from loop. From mysql I get data as object, and this data view like this:
|id|nazwa|link|parent|
|1|abc|abcc|0|
|2|aaa|bbb|1|
|3|aas|bbc|2|
|4|asdasd|adsasd|2|
|5|asdasd|serae|4|
|6|rywer|twet|0|
And now I need array whose use data from mysql and display it at array like this:
array(
[1]=>array(
id=>1,
nazwa=>abc
link=>abcc
child=>array(
[2]=>array(
id=>2,
nazwa=>aaa
link=>bbb
child=>array(
[3]=>array(
id=>3,
nazwa=>aas
link=>bbc
child=>array(
)
),
[4]=>array(
id=>4,
nazwa=>asdasd
link=>adsasd
child=>array(
[5]=>array(
id=>5,
nazwa=>asdasd
link=>serae
child=>array(
)
),
)
),
)
)
)
),
[6]=>array(
id=>6,
nazwa=>rywer
link=>twet
child=>array(
)
),
)
I think just a simple, good loop or function but I can not deal with it.
Upvotes: 0
Views: 162
Reputation: 4481
Try my code link to online demo:
<?php
$data = array(
array(
'id' => 1,
'name' => 'abc',
'link' => 'abcc',
'parent' => 0
),
array(
'id' => 2,
'name' => 'aaa',
'link' => 'bbb',
'parent' => 1
),
array(
'id' => 3,
'name' => 'aas',
'link' => 'bbc',
'parent' => 2
),
array(
'id' => 4,
'name' => 'asdasd',
'link' => 'adsasd',
'parent' => 2
),
array(
'id' => 5,
'name' => 'asdasd',
'link' => 'serae',
'parent' => 4
),
array(
'id' => 6,
'name' => 'rywer',
'link' => 'twet',
'parent' => 0
)
);
function buildMenu($data) {
usort($data, function($a, $b) {
if ($a['parent'] == $b['parent']) {
if ($a['id'] == $b['id']) {
return 0;
}
return ($a['id'] < $b['id']) ? -1 : 1;
}
return ($a['parent'] < $b['parent']) ? -1 : 1;
});
$shortcuts = array();
$menu = array();
foreach($data as &$row) {
if ($row['parent'] <= 0) {
$menu[] = &$row;
$shortcuts[$row['id']] = &$row;
continue;
} else {
$parent = $row['parent'];
if (!isset($shortcuts[$parent])) {
throw new \Exception("Menu cannot be build");
}
$parentItem = &$shortcuts[$parent];
}
if (!isset($parentItem['child'])) {
$parentItem['child'] = array();
}
$parentItem['child'][] = &$row;
$shortcuts[$row['id']] = &$row;
}
return $menu;
}
print_r(buildMenu($data));
It uses references to keep it clean. On the beggining of buildMenu function I have also sorted your sorce array to have data sorted by parent ID, increasingly.
Please also consider using english variable names.
If you would like to generate <ul>
menu from this array, use this code:
$menu = '<ul>';
function buildUl($data) {
$menuHtml = '';
foreach ($data as $menuItem) {
$menuHtml .= '<li>';
$menuHtml .= '<a href="'.$menuItem['link'].'">'.$menuItem['name'].'</a>';
if (!empty($menuItem['child'])) {
$menuHtml .= '<ul>';
$menuHtml .= buildUl($menuItem['child']);
$menuHtml .= '</ul>';
}
$menuHtml .= '</li>';
}
return $menuHtml;
}
$menu .= buildUl(buildMenu($data));
$menu .= '</ul>';
echo $menu;
Updated example: http://sandbox.onlinephpfunctions.com/code/27cfa95c066be9b1526b71566e2ec2f2093bdc34
Upvotes: 1
Reputation: 31832
Things are way easier when you use objects:
$data = [
['id' => 1, 'nazwa' => 'abc', 'link' => 'abcc', 'parent' => 0],
['id' => 2, 'nazwa' => 'aaa', 'link' => 'bbb', 'parent' => 1],
['id' => 3, 'nazwa' => 'aas', 'link' => 'bbc', 'parent' => 2],
['id' => 4, 'nazwa' => 'asdasd', 'link' => 'adsasd', 'parent' => 2],
['id' => 5, 'nazwa' => 'asdasd', 'link' => 'serae', 'parent' => 4],
['id' => 6, 'nazwa' => 'rywer', 'link' => 'twet', 'parent' => 0],
];
$objectTree = [];
$objects = [];
foreach ($data as $row) {
$obj = (object)$row;
$obj->childs = [];
$objects[$obj->id] = $obj;
}
foreach ($objects as $obj) {
if ($obj->parent == 0) {
$objectTree[] = $obj;
} else {
$objects[$obj->parent]->childs[] = $obj;
}
}
var_export($objectTree);
Demo: http://rextester.com/RZRQLX19028
Upvotes: 1