Related
There is an array of data obtained by Rest API. I am trying to make a menu from this data, but for this I need to convert it with regard to nesting (I think this is done in a loop)
I rummaged through the Internet, everywhere recursion with usual numeric id, and my id is a string, I tried to do it myself through foreach, it turned out
foreach ($elements as $item){
$thisRef = &$ref[$item['objectId']];
$thisRef['parent'] = &$item['parent'];
$thisRef['name'] = $item['property']['ru']['value'];
$thisRef['objectId'] = $item['objectId'];
$thisRef['number'] = $item['number'];
$thisRef['duration'] = $item['duration'];
$thisRef['object'] = $item['object'];
$thisRef['listorder'] = $item['listorder'];
if($item['parent'] == 0) {
$items[$item['objectId']] = &$thisRef;
} else {
$ref[$item['parent']]['child'][$item['objectId']] = &$thisRef;
}
}
print_r($items);
The cycle written by me works poorly, it displays a branch only up to level 2
array of $elements spread below in print_r and var_export
[objectId] is the id of the item
[parent] is the parent of the element, it refers to the parent's objectId, if it is empty or equal to 0, then it has no parent
A big request to offer a solution with unlimited nesting.
I hope you are will help me.
Array through print_r
Array
(
[0] => Array
(
[parent] => D0384DBB-F67C-FE92-FF46-F192B3F83B00
[created] => 1540568545112
[element_id] =>
[ownerId] =>
[type] =>
[duration] =>
[number] => 1
[start_time] =>
[enable] =>
[tiam] =>
[listorder] => 1
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[updated] => 1540569546246
[value] =>
[objectId] => 0DE56A96-9FA9-64E0-FFAB-97A246517200
[object] => round
[___class] => Elements
[property] => Array
(
[ru] => Array
(
[language_code] => ru
[created] => 1540568545865
[lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800
[element_id] => 0DE56A96-9FA9-64E0-FFAB-97A246517200
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[type] =>
[ownerId] =>
[value] => Раунд
[updated] =>
[objectId] => C28EE86F-71BC-A6D3-FFF6-707638303500
[object] => round
[___class] => Elements_values
)
)
)
[1] => Array
(
[parent] =>
[created] => 1540540322673
[element_id] =>
[ownerId] =>
[type] =>
[duration] =>
[number] => 1
[start_time] =>
[enable] =>
[tiam] =>
[listorder] => 1
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[updated] => 1540564573693
[value] =>
[objectId] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00
[object] => team
[___class] => Elements
[property] => Array
(
[ru] => Array
(
[language_code] => ru
[created] => 1540540323417
[lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800
[element_id] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[type] =>
[ownerId] =>
[value] => Команда
[updated] =>
[objectId] => 2B2C86CF-E1F8-5D2C-FF0E-1DB592CC7500
[object] => team
[___class] => Elements_values
)
)
)
[2] => Array
(
[parent] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00
[created] => 1540567572958
[element_id] =>
[ownerId] =>
[type] =>
[duration] =>
[number] => 1
[start_time] =>
[enable] =>
[tiam] =>
[listorder] => 1
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[updated] => 1540567674259
[value] =>
[objectId] => D0384DBB-F67C-FE92-FF46-F192B3F83B00
[object] => stage
[___class] => Elements
[property] => Array
(
[ru] => Array
(
[language_code] => ru
[created] => 1540567573722
[lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800
[element_id] => D0384DBB-F67C-FE92-FF46-F192B3F83B00
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[type] =>
[ownerId] =>
[value] => Этап
[updated] =>
[objectId] => 4E694471-70B3-C12B-FF79-97895532DD00
[object] => stage
[___class] => Elements_values
)
)
)
[3] => Array
(
[parent] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00
[created] => 1540565297592
[element_id] =>
[ownerId] =>
[type] =>
[duration] =>
[number] => 1
[start_time] =>
[enable] =>
[tiam] =>
[listorder] => 1
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[updated] => 1540565310503
[value] =>
[objectId] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00
[object] => route
[___class] => Elements
[property] => Array
(
[ru] => Array
(
[language_code] => ru
[created] => 1540565298342
[lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800
[element_id] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00
[quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00
[type] =>
[ownerId] =>
[value] => Маршрут
[updated] =>
[objectId] => 9CD62B6E-EACF-2911-FF57-3FF369F2BE00
[object] => route
[___class] => Elements_values
)
)
)
)
Array through var_export
array (
0 =>
array (
'parent' => 'D0384DBB-F67C-FE92-FF46-F192B3F83B00',
'created' => 1540568545112,
'element_id' => NULL,
'ownerId' => NULL,
'type' => NULL,
'duration' => NULL,
'number' => '1',
'start_time' => NULL,
'enable' => NULL,
'tiam' => NULL,
'listorder' => '1',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'updated' => 1540569546246,
'value' => NULL,
'objectId' => '0DE56A96-9FA9-64E0-FFAB-97A246517200',
'object' => 'round',
'___class' => 'Elements',
'property' =>
array (
'ru' =>
array (
'language_code' => 'ru',
'created' => 1540568545865,
'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800',
'element_id' => '0DE56A96-9FA9-64E0-FFAB-97A246517200',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'type' => NULL,
'ownerId' => NULL,
'value' => 'Раунд',
'updated' => NULL,
'objectId' => 'C28EE86F-71BC-A6D3-FFF6-707638303500',
'object' => 'round',
'___class' => 'Elements_values',
),
),
),
1 =>
array (
'parent' => NULL,
'created' => 1540540322673,
'element_id' => NULL,
'ownerId' => NULL,
'type' => NULL,
'duration' => NULL,
'number' => '1',
'start_time' => NULL,
'enable' => NULL,
'tiam' => NULL,
'listorder' => '1',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'updated' => 1540564573693,
'value' => NULL,
'objectId' => '4449513D-1CDD-00EA-FFDF-1947E4FDEA00',
'object' => 'team',
'___class' => 'Elements',
'property' =>
array (
'ru' =>
array (
'language_code' => 'ru',
'created' => 1540540323417,
'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800',
'element_id' => '4449513D-1CDD-00EA-FFDF-1947E4FDEA00',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'type' => NULL,
'ownerId' => NULL,
'value' => 'Команда',
'updated' => NULL,
'objectId' => '2B2C86CF-E1F8-5D2C-FF0E-1DB592CC7500',
'object' => 'team',
'___class' => 'Elements_values',
),
),
),
2 =>
array (
'parent' => 'F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00',
'created' => 1540567572958,
'element_id' => NULL,
'ownerId' => NULL,
'type' => NULL,
'duration' => NULL,
'number' => '1',
'start_time' => NULL,
'enable' => NULL,
'tiam' => NULL,
'listorder' => '1',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'updated' => 1540567674259,
'value' => NULL,
'objectId' => 'D0384DBB-F67C-FE92-FF46-F192B3F83B00',
'object' => 'stage',
'___class' => 'Elements',
'property' =>
array (
'ru' =>
array (
'language_code' => 'ru',
'created' => 1540567573722,
'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800',
'element_id' => 'D0384DBB-F67C-FE92-FF46-F192B3F83B00',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'type' => NULL,
'ownerId' => NULL,
'value' => 'Этап',
'updated' => NULL,
'objectId' => '4E694471-70B3-C12B-FF79-97895532DD00',
'object' => 'stage',
'___class' => 'Elements_values',
),
),
),
3 =>
array (
'parent' => '4449513D-1CDD-00EA-FFDF-1947E4FDEA00',
'created' => 1540565297592,
'element_id' => NULL,
'ownerId' => NULL,
'type' => NULL,
'duration' => NULL,
'number' => '1',
'start_time' => NULL,
'enable' => NULL,
'tiam' => NULL,
'listorder' => '1',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'updated' => 1540565310503,
'value' => NULL,
'objectId' => 'F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00',
'object' => 'route',
'___class' => 'Elements',
'property' =>
array (
'ru' =>
array (
'language_code' => 'ru',
'created' => 1540565298342,
'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800',
'element_id' => 'F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00',
'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00',
'type' => NULL,
'ownerId' => NULL,
'value' => 'Маршрут',
'updated' => NULL,
'objectId' => '9CD62B6E-EACF-2911-FF57-3FF369F2BE00',
'object' => 'route',
'___class' => 'Elements_values',
),
),
),
)
I need format array
Format example
Array
(
......
[4449513D-1CDD-00EA-FFDF-1947E4FDEA00] => Array
(
[parent] =>
[name] => Команда
[objectId] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00
[number] => 1
[duration] =>
[object] => team
[listorder] => 1
[child] => Array
(
[F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00] => Array
(
[parent] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00
[name] => Маршрут
[objectId] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00
[number] => 1
[duration] =>
[object] => route
[listorder] => 1
[child]=> Array
(
[D0384DBB-F67C-FE92-FF46-F192B3F83B00] => Array
(
[parent] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00
[name] => Этап
[objectId] => D0384DBB-F67C-FE92-FF46-F192B3F83B00
[number] => 1
[duration] =>
[object] => stage
[listorder] => 1
)
)
)
)
....
)
)
Try this:
function cascadeElements($elements, &$result, $index = 0, $parent = null) {
$next = function () use ($elements, &$result, $index, $parent) {
cascadeElements($elements, $result, ++$index, $parent);
};
if ($index >= count($elements)) {
return;
}
$element = $elements[$index];
if (!$parent && $element['parent'] !== null) {
return $next();
}
if ($parent && $element['parent'] !== $parent['objectId']) {
return $next();
}
$element['children'] = [];
cascadeElements($elements, $element['children'], 0, $element);
$result[$element['objectId']] = $element;
return $next();
}
You use it like this:
$result = [];
cascadeElements($data, $result);
$result will get filled with objectId keyed hierarchical list of elements where each element has it's children under children key.
This function should work for infinite amount of nesting.
I believe you want to loop through all of the items, current item as $current. If it has a parent, find the parent object $parent and then add the item to the parent's children array($parent.children[] = $current).
// Loop through all
foreach ($elements as $current) {
if (!empty($current['parent'])) {
// Loop through all if they have a parent
foreach ($elements as $parent) {
// Add $current as a child if this is the parent
if ($current['parent'] === $parent['objectId']) {
$parent['children'][] = $current;
}
}
}
}
If you only want parents in the array, you might be able to unset() or just make a new array by checking if the element doesn't have a parent.
I have an array of StdClass Objects and want to return the "partner_code" with the minimum value for key "price". So for this example I would like to return partner_code "AC" as it is the partner with the lowest price. I tried using array_reduce, but I'm not sure what I'm doing wrong. Any help would be appreciated. Please note I am not looking to SORT this array. I just want to move the subarray containing AC (because it hold the lowest price) to the top - not sorting everything by price
Input Array:
Array
(
[0] => stdClass Object
(
[name] => Budget
[partner_code] => BU
[price] => 365.36
[tier] => 1
)
[1] => stdClass Object
(
[name] => Avis
[partner_code] => AV
[price] => 449.71
[tier] => 1
)
[2] => stdClass Object
(
[name] => E-Z
[partner_code] => EZ
[price] => 270.56
[tier] => 2
)
[3] => stdClass Object
(
[name] => Sixt
[partner_code] => SX
[price] => 280.52
[tier] => 2
)
[4] => stdClass Object
(
[name] => Alamo
[partner_code] => AL
[price] => 345.13
[tier] => 2
)
[5] => stdClass Object
(
[name] => Advantage
[partner_code] => AD
[price] => 357.61
[tier] => 2
)
[6] => stdClass Object
(
[name] => Enterprise
[partner_code] => ET
[price] => 364.46
[tier] => 2
)
[7] => stdClass Object
(
[name] => ACE
[partner_code] => AC
[price] => 186.53
[tier] => 3
)
[8] => stdClass Object
(
[name] => Fox
[partner_code] => FX
[price] => 265.25
[tier] => 3
)
[9] => stdClass Object
(
[name] => Payless
[partner_code] => ZA
[price] => 380.47
[tier] => 3
)
[10] => stdClass Object
(
[name] => Dollar
[partner_code] => ZR
[price] => 385.99
[tier] => 3
)
[11] => stdClass Object
(
[name] => Thrifty
[partner_code] => ZT
[price] => 385.99
[tier] => 3
)
[12] => stdClass Object
(
[name] => Silvercar
[partner_code] => SC
[price] => 424.10
[tier] => 3
)
[13] => stdClass Object
(
[name] => National
[partner_code] => NA
[price] => 448.82
[tier] => 3
)
[14] => stdClass Object
(
[name] => Hertz
[partner_code] => HZ
[price] => 487.33
[tier] => 3
)
)
Code:
array_reduce($this->results->companies, function($a,$b) {
echo "Prices: " . $a->price . "<br>";
return $a->price < $b->price ? (string)$a->partner_code : (string)$b->partner_code;
});
usort($array, function($a, $b) {
return ($a->price - $b->price) ;
});
echo $array[0]->partner_code;
If you really don't want to sort the array but instead use array_reduce, do so by reducing the array to one of its elements. Then you can get the partner_code property for that element.
For example
array_reduce($this->results->companies, function($lowest, $company) {
// $lowest will be null on the first iteration
return $lowest === null || $company->price < $lowest->price ?
$company : $lowest;
})->partner_code;
This method will not sort the entire array. It will pull out the subarray with the lowest price and set it as the first element. I could have nested some of the functions to make it more compact (1-liner), but that would have damaged readability.
Code: (Demo)
$results=[
(object)["name"=>"Budget","partner_code"=>"BU","price"=>"365.36","tier"=>"1"],
(object)["name"=>"Avis","partner_code"=>"AV","price"=>"449.71","tier"=>"1"],
(object)["name"=>"E-Z","partner_code"=>"EZ","price"=>"270.56","tier"=>"2"],
(object)["name"=>"Sixt","partner_code"=>"SX","price"=>"280.52","tier"=>"2"],
(object)["name"=>"Alamo","partner_code"=>"AL","price"=>"345.13","tier"=>"2"],
(object)["name"=>"Advantage","partner_code"=>"AD","price"=>"357.61","tier"=>"2"],
(object)["name"=>"Enterprise","partner_code"=>"ET","price"=>"364.46","tier"=>"2"],
(object)["name"=>"ACE","partner_code"=>"AC","price"=>"186.53","tier"=>"3"],
(object)["name"=>"Fox","partner_code"=>"FX","price"=>"265.25","tier"=>"3"],
(object)["name"=>"Payless","partner_code"=>"ZA","price"=>"380.47","tier"=>"3"],
(object)["name"=>"Dollar","partner_code"=>"ZR","price"=>"385.99","tier"=>"3"],
(object)["name"=>"Thrifty","partner_code"=>"ZT","price"=>"385.99","tier"=>"3"],
(object)["name"=>"Silvercar","partner_code"=>"SC","price"=>"424.10","tier"=>"3"],
(object)["name"=>"National","partner_code"=>"NA","price"=>"448.82","tier"=>"3"],
(object)["name"=>"Hertz","partner_code"=>"HZ","price"=>"487.33","tier"=>"3"]
];
$min=min(array_column($results,'price')); // find the minimum value
$index=array_search($min,array_column($results,'price')); // find the index of the subarray containing min value
$pulled=array_splice($results,$index,1); // extract the subarray and preserve it as $pulled
$new_results=array_merge($pulled,$results); // set $pulled as first element
var_export($new_results);
...okay, okay, here's the one-liner:
var_export(array_merge(array_splice($results,array_search(min(array_column($results,'price')),array_column($results,'price')),1),$results));
Output:
array (
0 =>
stdClass::__set_state(array(
'name' => 'ACE',
'partner_code' => 'AC',
'price' => '186.53',
'tier' => '3',
)),
1 =>
stdClass::__set_state(array(
'name' => 'Budget',
'partner_code' => 'BU',
'price' => '365.36',
'tier' => '1',
)),
2 =>
stdClass::__set_state(array(
'name' => 'Avis',
'partner_code' => 'AV',
'price' => '449.71',
'tier' => '1',
)),
3 =>
stdClass::__set_state(array(
'name' => 'E-Z',
'partner_code' => 'EZ',
'price' => '270.56',
'tier' => '2',
)),
4 =>
stdClass::__set_state(array(
'name' => 'Sixt',
'partner_code' => 'SX',
'price' => '280.52',
'tier' => '2',
)),
5 =>
stdClass::__set_state(array(
'name' => 'Alamo',
'partner_code' => 'AL',
'price' => '345.13',
'tier' => '2',
)),
6 =>
stdClass::__set_state(array(
'name' => 'Advantage',
'partner_code' => 'AD',
'price' => '357.61',
'tier' => '2',
)),
7 =>
stdClass::__set_state(array(
'name' => 'Enterprise',
'partner_code' => 'ET',
'price' => '364.46',
'tier' => '2',
)),
8 =>
stdClass::__set_state(array(
'name' => 'Fox',
'partner_code' => 'FX',
'price' => '265.25',
'tier' => '3',
)),
9 =>
stdClass::__set_state(array(
'name' => 'Payless',
'partner_code' => 'ZA',
'price' => '380.47',
'tier' => '3',
)),
10 =>
stdClass::__set_state(array(
'name' => 'Dollar',
'partner_code' => 'ZR',
'price' => '385.99',
'tier' => '3',
)),
11 =>
stdClass::__set_state(array(
'name' => 'Thrifty',
'partner_code' => 'ZT',
'price' => '385.99',
'tier' => '3',
)),
12 =>
stdClass::__set_state(array(
'name' => 'Silvercar',
'partner_code' => 'SC',
'price' => '424.10',
'tier' => '3',
)),
13 =>
stdClass::__set_state(array(
'name' => 'National',
'partner_code' => 'NA',
'price' => '448.82',
'tier' => '3',
)),
14 =>
stdClass::__set_state(array(
'name' => 'Hertz',
'partner_code' => 'HZ',
'price' => '487.33',
'tier' => '3',
)),
)
I think this is a leaner method generating the same/desired result: (Demo)
$min=$results[0]->price; // set initial/default min value
$index=0; // set initial/default index
foreach($results as $i=>$a){
if($a->price<$min){ // if a lower price...
$min=$a->price; // store new $min
$index=$i; // stor new $index
}
}
$results=array_merge($results,array_splice($results,$index,1)); // extract lowest and move to front of array
var_export($results);
I have a tree like below, which contains the nth level permission.
Landing Page Footer Archive
|| || ||
|| || ||
Current ========== Pipeline=== BHI Phonebook==Password Keeper Edit==View==Delete
|| ||
Open Forms Open Forms
|| ||
Blog Request Blog Request
|| ||
Add == Edit Add == Edit
Sample Array
$list = Array
(
[0] => Array
(
[parent] => 0
[item_level] => 1
[id] => 1
[display_name] => Landing Page
)
[1] => Array
(
[parent] => 1
[item_level] => 2
[id] => 2
[display_name] => Current
)
[2] => Array
(
[parent] => 2
[item_level] => 3
[id] => 5
[display_name] => Open Forms
)
[3] => Array
(
[parent] => 5
[item_level] => 4
[id] => 9
[display_name] => Blog Request
)
[4] => Array
(
[parent] => 9
[item_level] => 5
[id] => 10
[display_name] => Add
)
[5] => Array
(
[parent] => 9
[item_level] => 5
[id] => 11
[display_name] => Update
)
[6] => Array
(
[parent] => 1
[item_level] => 2
[id] => 3
[display_name] => Pipeline
)
[7] => Array
(
[parent] => 3
[item_level] => 3
[id] => 6
[display_name] => Open Forms
)
[8] => Array
(
[parent] => 6
[item_level] => 4
[id] => 12
[display_name] => Blog Request
)
[9] => Array
(
[parent] => 12
[item_level] => 5
[id] => 13
[display_name] => Add
)
[10] => Array
(
[parent] => 12
[item_level] => 5
[id] => 14
[display_name] => Update
)
[11] => Array
(
[parent] => 1
[item_level] => 2
[id] => 4
[display_name] => BHI
)
[12] => Array
(
[parent] => 1
[item_level] => 2
[id] => 7
[display_name] => Add Property
)
[13] => Array
(
[parent] => 1
[item_level] => 2
[id] => 8
[display_name] => Show Child Properties
)
[14] => Array
(
[parent] => 0
[item_level] => 1
[id] => 15
[display_name] => Footer
)
[15] => Array
(
[parent] => 15
[item_level] => 2
[id] => 16
[display_name] => Phonebook
)
[16] => Array
(
[parent] => 15
[item_level] => 2
[id] => 17
[display_name] => Password Keeper
)
[17] => Array
(
[parent] => 0
[item_level] => 1
[id] => 18
[display_name] => Archive
)
[18] => Array
(
[parent] => 18
[item_level] => 2
[id] => 19
[display_name] => Edit
)
[19] => Array
(
[parent] => 18
[item_level] => 2
[id] => 20
[display_name] => View
)
[20] => Array
(
[parent] => 18
[item_level] => 2
[id] => 21
[display_name] => Delete
)
)
Expected Output
//Here Key is the value of "id" attribute
$final_output = array(
1 => array(
2=>array(5=>array(9=>array(10,11))),
3=>array(6=>array(12=>array(13,14))),
4,//As it doesnt have any child
7,//As it doesnt have any child
8 //As it doesnt have any child
),
15 => array(
16, //As it doesnt have any child
17 ////As it doesnt have any child
),
18 => array(
19, //As it doesnt have any child
20, ////As it doesnt have any child
21 ////As it doesnt have any child
),
);
here, 1: Landing Page ,15 : Footer ,18 : Archive (its "Id" attribute) etc.
After above array i will have to do a nth level loop.
like:
foreach($final_output as $res)
{
if(is_array($res))
{
//Then do something, i am not sure how this achivable
}
}
What i have done so far, but no success.
//To find out the how manhy levels are in array
$unique_level = array_unique(array_map(function ($i) { return $i['item_level']; }, $list));
$parent_data = $level_data = array();
foreach($list as $key=>$res)
{
if($res['parent']==0)
{
if(!array_key_exists($res['id'],$parent_data)) // First insert all unique parent at level 1
{
$parent_data[$res['id']] = $res;
}
}
$level_data[$res['parent']][] = array(
'display_name' => $res['display_name'],
'id' => $res['id'],
'parent' => $res['parent'],
);
}
Ready to use json
[{"parent":"0","item_level":"1","id":"1","display_name":"Landing Page"},{"parent":"1","item_level":"2","id":"2","display_name":"Current"},{"parent":"2","item_level":"3","id":"5","display_name":"Open Forms"},{"parent":"5","item_level":"4","id":"9","display_name":"Blog Request"},{"parent":"9","item_level":"5","id":"10","display_name":"Add"},{"parent":"9","item_level":"5","id":"11","display_name":"Update"},{"parent":"1","item_level":"2","id":"3","display_name":"Pipeline"},{"parent":"3","item_level":"3","id":"6","display_name":"Open Forms"},{"parent":"6","item_level":"4","id":"12","display_name":"Blog Request"},{"parent":"12","item_level":"5","id":"13","display_name":"Add"},{"parent":"12","item_level":"5","id":"14","display_name":"Update"},{"parent":"1","item_level":"2","id":"4","display_name":"BHI"},{"parent":"1","item_level":"2","id":"7","display_name":"Add Property"},{"parent":"1","item_level":"2","id":"8","display_name":"Show Child Properties"},{"parent":"0","item_level":"1","id":"15","display_name":"Footer"},{"parent":"15","item_level":"2","id":"16","display_name":"Phonebook"},{"parent":"15","item_level":"2","id":"17","display_name":"Password Keeper"},{"parent":"0","item_level":"1","id":"18","display_name":"Archive"},{"parent":"18","item_level":"2","id":"19","display_name":"Edit"},{"parent":"18","item_level":"2","id":"20","display_name":"View"},{"parent":"18","item_level":"2","id":"21","display_name":"Delete"}]
The nearest I've got is...
$list = json_decode($data, true);
$baseList = array_combine(array_column($list,'id'), $list);
$hierarchy = [];
foreach ( $baseList as $newItem ) {
$parent = $newItem['parent'];
$hierarchy[$parent][] = $newItem['id'];
}
function buildTree ( $startNode, $hierarchy) {
$newLevel = [];
foreach ( $startNode as $children ) {
if ( isset($hierarchy[$children])) {
$newLevel[$children] = buildTree($hierarchy[$children], $hierarchy);
}
else {
$newLevel[$children] = $children;
}
}
return $newLevel;
}
$finalOutput = buildTree ( $hierarchy[0], $hierarchy );
print_r($finalOutput);
The problem you have is where you have elements like...
1 => array(
2=>array(5=>array(9=>array(10,11))),
3=>array(6=>array(12=>array(13,14))),
4,//As it doesnt have any child
7,//As it doesnt have any child
8 //As it doesnt have any child
),
As you almost have elements 4, 7 and 8 which don't have a key - all elements in an array have a key, this isn't going to work.
The output which I've done is...
Array
(
[1] => Array
(
[2] => Array
(
[5] => Array
(
[9] => Array
(
[10] => 10
[11] => 11
)
)
)
[3] => Array
(
[6] => Array
(
[12] => Array
(
[13] => 13
[14] => 14
)
)
)
[4] => 4
[7] => 7
[8] => 8
)
[15] => Array
(
[16] => 16
[17] => 17
)
[18] => Array
[19] => 19
[20] => 20
[21] => 21
)
) [19] => 19
[20] => 20
[21] => 21
)
)
Which as you can see, has element 4 having a value of 4.
$list = Array
(
0 => Array
(
'parent' => 0,
'item_level' => 1,
'id' => 1,
'display_name' => 'Landing Page'
),
1 => Array
(
'parent' => 1,
'item_level' => 2,
'id' => 2,
'display_name' => 'Current'
),
2 => Array
(
'parent' => 2,
'item_level' => 3,
'id' => 5,
'display_name' => 'Open Forms'
),
3 => Array
(
'parent' => 5,
'item_level' => 4,
'id' => 9,
'display_name' => 'Blog Request'
),
4 => Array
(
'parent' => 9,
'item_level' => 5,
'id' => 10,
'display_name' => 'Add'
),
5 => Array
(
'parent' => 9,
'item_level' => 5,
'id' => 11,
'display_name' => 'Update'
),
6 => Array
(
'parent' => 1,
'item_level' => 2,
'id' => 3,
'display_name' => 'Pipeline'
),
7 => Array
(
'parent' => 3,
'item_level' => 3,
'id' => 6,
'display_name' => 'Open Forms'
),
8 => Array
(
'parent' => 6,
'item_level' => 4,
'id' => 12,
'display_name' => 'Blog Request'
),
9 => Array
(
'parent' => 12,
'item_level' => 5,
'id' => 13,
'display_name' => 'Add'
),
10 => Array
(
'parent' => 12,
'item_level' => 5,
'id' => 14,
'display_name' => 'Update'
),
11 => Array
(
'parent' => 1,
'item_level' => 2,
'id' => 4,
'display_name' => 'BHI'
),
12 => Array
(
'parent' => 1,
'item_level' => 2,
'id' => 7,
'display_name' => 'Add Property'
),
13 => Array
(
'parent' => 1,
'item_level' => 2,
'id' => 8,
'display_name' => 'Show Child Properties'
),
14 => Array
(
'parent' => 0,
'item_level' => 1,
'id' => 15,
'display_name' => 'Footer'
),
15 => Array
(
'parent' => 15,
'item_level' => 2,
'id' => 16,
'display_name' => 'Phonebook'
),
16 => Array
(
'parent' => 15,
'item_level' => 2,
'id' => 17,
'display_name' => 'Password Keeper'
),
17 => Array
(
'parent' => 0,
'item_level' => 1,
'id' => 18,
'display_name' => 'Archive'
),
18 => Array
(
'parent' => 18,
'item_level' => 2,
'id' => 19,
'display_name' => 'Edit'
),
19 => Array
(
'parent' => 18,
'item_level' => 2,
'id' => 20,
'display_name' => 'View'
),
20 => Array
(
'parent' => 18,
'item_level' => 2,
'id' => 21,
'display_name' => 'Delete'
),
);
Hi, try this code:
$results=array();
$parent1='';$parent=$parent2='';
foreach ($list as $key => $value) {
if($value['parent']==0)
{
$results[$value['id']]=$value;
$id=$value["id"];
}
if($id==$value['parent']&&$id!="")
{
$results[$id][$value['id']]=$value;
$parent=$value['id'];
}
if($parent==$value['parent']&&$parent!="")
{
$results[$id][$parent][$value['id']]=$value;
$parent1=$value['id'];
}
if($parent1==$value['parent']&&$parent1!="")
{
$results[$id][$parent][$parent1][$value['id']]=$value;
$parent2=$value['id'];
}
if($parent2==$value['parent']&&$parent2!="")
{
$results[$id][$parent][$parent1][$parent2][$value['id']]=$value;
$parent3=$value['id'];
}
}
echo '<pre>';
print_r($results);
echo '</pre>';
The MySQL navigation table uses id, parent_id, name to have an unlimited navigation depth. I am using a recursive function to create the multidimensional array, that works. What I have been trying for hours is to create a function that puts the path (/mainitem/subitem/subsubsitem/subsubsubitem/ etc in the menu_nl of the menu table:
$q = "
SELECT m.id, m.parent_id, m.menu_nl, parents.menu_nl AS 'parent'
FROM menu AS m
LEFT JOIN menu AS parents ON parents.id = m.parent_id
ORDER BY m.parent_id ASC, m.volgorde ASC";
$r = $dbcon->query($q);
$pages = $r->fetchAll(PDO::FETCH_ASSOC);
function create_array(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = create_array($elements, $element['id']);
if ($children) {
$element[$element['menu_nl']] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
$tree = create_array($pages);
A var_export looks this:
array (
0 =>
array (
'id' => 34,
'parent_id' => 0,
'menu_nl' => 'INTRODUCTION',
'parent' => NULL,
),
1 =>
array (
'id' => 36,
'parent_id' => 0,
'menu_nl' => 'TEAM',
'parent' => NULL,
'TEAM' =>
array (
0 =>
array (
'id' => 133,
'parent_id' => 36,
'menu_nl' => 'Team member A',
'parent' => 'TEAM',
),
1 =>
array (
'id' => 134,
'parent_id' => 36,
'menu_nl' => 'Team member B',
'parent' => 'TEAM',
),
),
),
2 =>
array (
'id' => 50,
'parent_id' => 0,
'menu_nl' => 'PRODUCTS',
'parent' => NULL,
'PRODUCTS' =>
array (
0 =>
array (
'id' => 151,
'parent_id' => 50,
'menu_nl' => 'SUB PRODUCT A',
'parent' => 'PRODUCTS',
'SUB PRODUCT A' =>
array (
0 =>
array (
'id' => 154,
'parent_id' => 151,
'menu_nl' => 'SUB OF SUB PRODUCT A',
'parent' => 'SUB PRODUCT A',
'SUB OF SUB PRODUCT A' =>
array (
0 =>
array (
'id' => 156,
'parent_id' => 154,
'menu_nl' => 'SUB OF SUB OF SUB PRODUCT A',
'parent' => 'SUB OF SUB PRODUCT A',
),
),
),
),
),
1 =>
array (
'id' => 152,
'parent_id' => 50,
'menu_nl' => 'SUB PRODUCT B',
'parent' => 'PRODUCTS',
'SUB PRODUCT B' =>
array (
0 =>
array (
'id' => 155,
'parent_id' => 152,
'menu_nl' => 'SUB OF SUB PRODUCTB',
'parent' => 'SUB PRODUCT B',
),
),
),
2 =>
array (
'id' => 153,
'parent_id' => 50,
'menu_nl' => 'SUB PRODUCT C',
'parent' => 'PRODUCTS',
),
),
),
3 =>
array (
'id' => 40,
'parent_id' => 0,
'menu_nl' => 'CONTACT',
'parent' => NULL,
'CONTACT' =>
array (
0 =>
array (
'id' => 139,
'parent_id' => 40,
'menu_nl' => 'Contact form',
'parent' => 'CONTACT',
),
1 =>
array (
'id' => 143,
'parent_id' => 40,
'menu_nl' => 'How to get there',
'parent' => 'CONTACT',
),
),
),
)
save the element's fullpath in the array as a concatenation of its parent's path with its own. Then pass that down as a parameter in your recursive function.
live demo
example repository
<?php
// add $parentpath parameter
function create_array(array $elements, $parentId = 0, $parentpath = '') {
$branch = array();
foreach ($elements as $element) {
// set the fullpath from parent concatenated to this menu_nl
$element['fullpath'] = "$parentpath/$element[menu_nl]";
if ($element['parent_id'] == $parentId) {
// pass the fullpath down to its children
$children = create_array($elements, $element['id'], $element['fullpath']);
if ($children) {
$element[$element['menu_nl']] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
$pages = require 'pages.php';
print_r( create_array($pages) );
Array
(
[0] => Array
(
[id] => 34
[parent_id] => 0
[menu_nl] => INTRODUCTION
[parent] =>
[fullpath] => /INTRODUCTION
)
[1] => Array
(
[id] => 36
[parent_id] => 0
[menu_nl] => TEAM
[parent] =>
[fullpath] => /TEAM
[TEAM] => Array
(
[0] => Array
(
[id] => 133
[parent_id] => 36
[menu_nl] => Team member A
[parent] => TEAM
[fullpath] => /TEAM/Team member A
)
[1] => Array
(
[id] => 134
[parent_id] => 36
[menu_nl] => Team member B
[parent] => TEAM
[fullpath] => /TEAM/Team member B
)
)
)
[2] => Array
(
[id] => 50
[parent_id] => 0
[menu_nl] => PRODUCTS
[parent] =>
[fullpath] => /PRODUCTS
[PRODUCTS] => Array
(
[0] => Array
(
[id] => 151
[parent_id] => 50
[menu_nl] => SUB PRODUCT A
[parent] => PRODUCTS
[fullpath] => /PRODUCTS/SUB PRODUCT A
[SUB PRODUCT A] => Array
(
[0] => Array
(
[id] => 154
[parent_id] => 151
[menu_nl] => SUB OF SUB PRODUCT A
[parent] => SUB PRODUCT A
[fullpath] => /PRODUCTS/SUB PRODUCT A/SUB OF SUB PRODUCT A
[SUB OF SUB PRODUCT A] => Array
(
[0] => Array
(
[id] => 156
[parent_id] => 154
[menu_nl] => SUB OF SUB OF SUB PRODUCT A
[parent] => SUB OF SUB PRODUCT A
[fullpath] => /PRODUCTS/SUB PRODUCT A/SUB OF SUB PRODUCT A/SUB OF SUB OF SUB PRODUCT A
)
)
)
)
)
[1] => Array
(
[id] => 152
[parent_id] => 50
[menu_nl] => SUB PRODUCT B
[parent] => PRODUCTS
[fullpath] => /PRODUCTS/SUB PRODUCT B
[SUB PRODUCT B] => Array
(
[0] => Array
(
[id] => 155
[parent_id] => 152
[menu_nl] => SUB OF SUB PRODUCTB
[parent] => SUB PRODUCT B
[fullpath] => /PRODUCTS/SUB PRODUCT B/SUB OF SUB PRODUCTB
)
)
)
[2] => Array
(
[id] => 153
[parent_id] => 50
[menu_nl] => SUB PRODUCT C
[parent] => PRODUCTS
[fullpath] => /PRODUCTS/SUB PRODUCT C
)
)
)
[3] => Array
(
[id] => 40
[parent_id] => 0
[menu_nl] => CONTACT
[parent] =>
[fullpath] => /CONTACT
[CONTACT] => Array
(
[0] => Array
(
[id] => 139
[parent_id] => 40
[menu_nl] => Contact form
[parent] => CONTACT
[fullpath] => /CONTACT/Contact form
)
[1] => Array
(
[id] => 143
[parent_id] => 40
[menu_nl] => How to get there
[parent] => CONTACT
[fullpath] => /CONTACT/How to get there
)
)
)
)
Pointless Dribble
Okay This is another weird one from me, i want to thank OIS for helping me out on my last question... which deals with this same kind of funky array manipulation... i studied that code in depth and i feel it has helped me become better with recursive array manipulative functions. However, once again i find my self in another tough spot
Actual Problem
I am trying to write a recursive manipulative function such as this. Except for getting the depth of each array element. It will add incremental count to each array element with a certain depth. The easiest way to see what I'm trying to do is to view the "sample array" and "Desired result Array"... i feel like I'm getting better at understanding these kind of recursive functions. but this one is giving me hell, thanks in advance for any kind of help you can give me with this.
Please disregard the [depth] result of the sample array i already have a function that adds this.
Thanks again,
-- YouDontMeanMuch
Sample Array
array (
52 =>
array (
'title' => 'Website Navigation',
'path' => '',
'type' => '115',
'pid' => 0,
'hasChildren' => 1,
'children' =>
array (
53 =>
array (
'title' => 'Home',
'path' => '',
'type' => '118',
'pid' => 52,
'hasChildren' => 0,
),
54 =>
array (
'title' => 'Features',
'path' => 'features',
'type' => '374',
'pid' => 52,
'hasChildren' => 1,
'children' =>
array (
59 =>
array (
'title' => 'artistic',
'path' => 'features/artistic',
'type' => '374',
'pid' => 54,
'hasChildren' => 1,
'children' =>
array (
63 =>
array (
'title' => 'galleries',
'path' => 'features/artistic/galleries',
'type' => '374',
'pid' => 59,
'hasChildren' => 1,
'children' =>
array (
65 =>
array (
'title' => 'graphics',
'path' => 'features/artistic/galleries/graphics',
'type' => '118',
'pid' => 63,
'hasChildren' => 0,
),
67 =>
array (
'title' => 'mixed medium',
'path' => 'features/artistic/galleries/mixed-medium',
'type' => '118',
'pid' => 63,
'hasChildren' => 0,
),
64 =>
array (
'title' => 'overview',
'path' => 'features/artistic/galleries',
'type' => '118',
'pid' => 63,
'hasChildren' => 0,
),
68 =>
array (
'title' => 'photography',
'path' => 'features/artistic/galleries/photography',
'type' => '118',
'pid' => 63,
'hasChildren' => 0,
),
66 =>
array (
'title' => 'traditional',
'path' => 'features/artistic/galleries/traditional',
'type' => '118',
'pid' => 63,
'hasChildren' => 0,
),
),
),
62 =>
array (
'title' => 'overview',
'path' => 'features/artistic',
'type' => '118',
'pid' => 59,
'hasChildren' => 0,
),
69 =>
array (
'title' => 'tutorials',
'path' => 'features/artistic/tutorials',
'type' => '374',
'pid' => 59,
'hasChildren' => 1,
'children' =>
array (
71 =>
array (
'title' => 'by category',
'path' => 'features/artistic/tutorials/by-category/',
'type' => '118',
'pid' => 69,
'hasChildren' => 0,
),
72 =>
array (
'title' => 'by date',
'path' => 'features/artistic/tutorials/by-date/',
'type' => '118',
'pid' => 69,
'hasChildren' => 0,
),
70 =>
array (
'title' => 'overview',
'path' => 'features/artistic/tutorials',
'type' => '118',
'pid' => 69,
'hasChildren' => 0,
),
),
),
),
),
58 =>
array (
'title' => 'overview',
'path' => 'features',
'type' => '118',
'pid' => 54,
'hasChildren' => 0,
),
61 =>
array (
'title' => 'projects / labs',
'path' => 'features/projects-labs/',
'type' => '374',
'pid' => 54,
'hasChildren' => 0,
),
60 =>
array (
'title' => 'web development',
'path' => 'features/web-development',
'type' => '374',
'pid' => 54,
'hasChildren' => 1,
'children' =>
array (
74 =>
array (
'title' => 'articles',
'path' => 'features/web-development/articles/',
'type' => '374',
'pid' => 60,
'hasChildren' => 0,
),
73 =>
array (
'title' => 'overview',
'path' => 'features/web-development',
'type' => '118',
'pid' => 60,
'hasChildren' => 0,
),
75 =>
array (
'title' => 'tutorials',
'path' => 'features/web-development/tutorials',
'type' => '374',
'pid' => 60,
'hasChildren' => 0,
),
),
),
),
),
55 =>
array (
'title' => 'Activity',
'path' => 'activity',
'type' => '374',
'pid' => 52,
'hasChildren' => 0,
),
56 =>
array (
'title' => 'Blog',
'path' => 'blog',
'type' => '374',
'pid' => 52,
'hasChildren' => 0,
),
57 =>
array (
'title' => 'About',
'path' => 'about',
'type' => '374',
'pid' => 52,
'hasChildren' => 1,
'children' =>
array (
76 =>
array (
'title' => 'the author',
'path' => 'about/the-author',
'type' => '118',
'pid' => 57,
'hasChildren' => 0,
),
77 =>
array (
'title' => 'the website',
'path' => 'about/the-website',
'type' => '118',
'pid' => 57,
'hasChildren' => 0,
),
),
),
),
),
)
Desired result Array Notice the [count] index
Array
(
[53] => Array
(
[title] => Home
[path] =>
[type] => 118
[pid] => 52
[mid] => 53
[hasChildren] => 0
[depth] => 1
[count] => 1
)
[54] => Array
(
[title] => Features
[path] => features
[type] => 374
[pid] => 52
[mid] => 54
[hasChildren] => 1
[depth] => 1
[count] => 2
[children] => Array
(
[59] => Array
(
[title] => artistic
[path] => features/artistic
[type] => 374
[pid] => 54
[mid] => 59
[hasChildren] => 1
[depth] => 2
[count] => 1
[children] => Array
(
[63] => Array
(
[title] => galleries
[path] => features/artistic/galleries
[type] => 374
[pid] => 59
[mid] => 63
[hasChildren] => 1
[depth] => 3
[count] => 1
[children] => Array
(
[65] => Array
(
[title] => graphics
[path] => features/artistic/galleries/graphics
[type] => 118
[pid] => 63
[mid] => 65
[hasChildren] => 0
[depth] => 4
[count] => 1
)
[67] => Array
(
[title] => mixed medium
[path] => features/artistic/galleries/mixed-medium
[type] => 118
[pid] => 63
[mid] => 67
[hasChildren] => 0
[depth] => 4
[count] => 2
)
[64] => Array
(
[title] => overview
[path] => features/artistic/galleries
[type] => 118
[pid] => 63
[mid] => 64
[hasChildren] => 0
[depth] => 4
[count] => 3
)
[68] => Array
(
[title] => photography
[path] => features/artistic/galleries/photography
[type] => 118
[pid] => 63
[mid] => 68
[hasChildren] => 0
[depth] => 4
[count] => 4
)
[66] => Array
(
[title] => traditional
[path] => features/artistic/galleries/traditional
[type] => 118
[pid] => 63
[mid] => 66
[hasChildren] => 0
[depth] => 4
[count] => 5
)
)
)
[62] => Array
(
[title] => overview
[path] => features/artistic
[type] => 118
[pid] => 59
[mid] => 62
[hasChildren] => 0
[depth] => 3
[count] => 2
)
[69] => Array
(
[title] => tutorials
[path] => features/artistic/tutorials
[type] => 374
[pid] => 59
[mid] => 69
[hasChildren] => 1
[depth] => 3
[count] => 3
[children] => Array
(
[71] => Array
(
[title] => by category
[path] => features/artistic/tutorials/by-category/
[type] => 118
[pid] => 69
[mid] => 71
[hasChildren] => 0
[depth] => 4
[count] => 1
)
[72] => Array
(
[title] => by date
[path] => features/artistic/tutorials/by-date/
[type] => 118
[pid] => 69
[mid] => 72
[hasChildren] => 0
[depth] => 4
[count] => 2
)
[70] => Array
(
[title] => overview
[path] => features/artistic/tutorials
[type] => 118
[pid] => 69
[mid] => 70
[hasChildren] => 0
[depth] => 4
[count] => 3
)
)
)
)
)
[58] => Array
(
[title] => overview
[path] => features
[type] => 118
[pid] => 54
[mid] => 58
[hasChildren] => 0
[depth] => 2
[count] => 2
)
[61] => Array
(
[title] => projects / labs
[path] => features/projects-labs/
[type] => 374
[pid] => 54
[mid] => 61
[hasChildren] => 0
[depth] => 2
[count] => 3
)
[60] => Array
(
[title] => web development
[path] => features/web-development
[type] => 374
[pid] => 54
[mid] => 60
[hasChildren] => 1
[depth] => 2
[count] => 4
[children] => Array
(
[74] => Array
(
[title] => articles
[path] => features/web-development/articles/
[type] => 374
[pid] => 60
[mid] => 74
[hasChildren] => 0
[depth] => 3
[count] => 1
)
[73] => Array
(
[title] => overview
[path] => features/web-development
[type] => 118
[pid] => 60
[mid] => 73
[hasChildren] => 0
[depth] => 3
[count] => 2
)
[75] => Array
(
[title] => tutorials
[path] => features/web-development/tutorials
[type] => 374
[pid] => 60
[mid] => 75
[hasChildren] => 0
[depth] => 3
[count] => 3
)
I think this should work... I wasn't able to test on your example array but it seems to work on a smaller array I made.
Edit: Changed the function now that you've removed the 'depth' keys from your example array. Now it finds the depth on its own. I've also added my test code and output:
<?php
function array_depth_count(&$array, $count=array(), $depth=1) {
foreach ($array as &$value) {
if (is_array($value)) {
$value['count'] = ++$count[$depth];
array_depth_count($value, $count, $depth + 1);
}
}
}
$a = array(array(array(array(0),array(0),array(),array()),0,array()));
echo "Before\n";
print_r($a);
array_depth_count($a);
echo "\n\nAfter\n";
print_r($a);
?>
Output:
Before
Array
(
[0] => Array
(
[0] => Array
(
[0] => Array
(
[0] => 0
)
[1] => Array
(
[0] => 0
)
[2] => Array
(
)
[3] => Array
(
)
)
[1] => 0
[2] => Array
(
)
)
)
After
Array
(
[0] => Array
(
[0] => Array
(
[0] => Array
(
[0] => 0
[count] => 1
)
[1] => Array
(
[0] => 0
[count] => 2
)
[2] => Array
(
[count] => 3
)
[3] => Array
(
[count] => 4
)
[count] => 1
)
[1] => 0
[2] => Array
(
[count] => 2
)
[count] => 1
)
)
I really want to say this will work
function deep(&$layer)
{
$count = 1;
$keys = array_keys($layer);
foreach($keys as $key)
if(is_array($layer[$key]))
deep($layer[$key]);
$layer['depth'] = $count++;
}
(Tested and works fine for me)
(Another case of me misunderstanding the question. This should be what you want)