How can I change array for the menu? - php

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.

Related

how to do a foreach loop values in a multidimensional array PHP

I'm working with Spotify API and I want to do a foreach loop for only the values in ['tracks'][0]["album"]["images"][2]['url']
How can I go about this?
I tried to do a foreach loop to retrieve value of each key associated inside the multidimensional associative array iterating through each element but can still get it to work.
Array
(
[tracks] => Array
(
[0] => Array
(
[album] => Array
(
[album_type] => album
[artists] => Array
(
[0] => Array
(
[external_urls] => Array
(
[spotify] => https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr
)
[href] => https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr
[id] => 4ovtyvs7j1jSmwhkBGHqSr
[name] => Olamide
[type] => artist
[uri] => spotify:artist:4ovtyvs7j1jSmwhkBGHqSr
)
)
[external_urls] => Array
(
[spotify] => https://open.spotify.com/album/6fG2eFCgUmytQWL6umtsCh
)
[href] => https://api.spotify.com/v1/albums/6fG2eFCgUmytQWL6umtsCh
[id] => 6fG2eFCgUmytQWL6umtsCh
[images] => Array
(
[0] => Array
(
[height] => 640
[url] => https://i.scdn.co/image/ab67616d0000b27387d20b9a27d5e14d74b5cb77
[width] => 640
)
[1] => Array
(
[height] => 300
[url] => https://i.scdn.co/image/ab67616d00001e0287d20b9a27d5e14d74b5cb77
[width] => 300
)
[2] => Array
(
[height] => 64
[url] => https://i.scdn.co/image/ab67616d0000485187d20b9a27d5e14d74b5cb77
[width] => 64
)
)
[name] => Carpe Diem
[release_date] => 2020-10-07
[release_date_precision] => day
[total_tracks] => 12
[type] => album
[uri] => spotify:album:6fG2eFCgUmytQWL6umtsCh
)
[artists] => Array
(
[0] => Array
(
[external_urls] => Array
(
[spotify] => https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr
)
[href] => https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr
[id] => 4ovtyvs7j1jSmwhkBGHqSr
[name] => Olamide
[type] => artist
[uri] => spotify:artist:4ovtyvs7j1jSmwhkBGHqSr
)
[1] => Array
(
[external_urls] => Array
(
[spotify] => https://open.spotify.com/artist/5yOvAmpIR7hVxiS6Ls5DPO
)
[href] => https://api.spotify.com/v1/artists/5yOvAmpIR7hVxiS6Ls5DPO
[id] => 5yOvAmpIR7hVxiS6Ls5DPO
[name] => Omah Lay
[type] => artist
[uri] => spotify:artist:5yOvAmpIR7hVxiS6Ls5DPO
)
)
[disc_number] => 1
[duration_ms] => 171764
[explicit] => 1
[external_ids] => Array
(
[isrc] => USUYG1330802
)
[external_urls] => Array
(
[spotify] => https://open.spotify.com/track/5DS9LiyEdw2zY8bM6kjjgM
)
[href] => https://api.spotify.com/v1/tracks/5DS9LiyEdw2zY8bM6kjjgM
[id] => 5DS9LiyEdw2zY8bM6kjjgM
[is_local] =>
[is_playable] => 1
[name] => Infinity (feat. Omah Lay)
[popularity] => 73
[preview_url] => https://p.scdn.co/mp3-preview/5159fa17676fc96e32db13b7680f7497d5c2f74d?cid=756f211306ad4c9a934d07c5722790b5
[track_number] => 3
[type] => track
[uri] => spotify:track:5DS9LiyEdw2zY8bM6kjjgM
)
[1] => Array
(
[album] => Array
(
[album_type] => album
[artists] => Array
(
[0] => Array
(
[external_urls] => Array
(
[spotify] => https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr
)
[href] => https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr
[id] => 4ovtyvs7j1jSmwhkBGHqSr
[name] => Olamide
[type] => artist
[uri] => spotify:artist:4ovtyvs7j1jSmwhkBGHqSr
)
)
[external_urls] => Array
(
[spotify] => https://open.spotify.com/album/6fG2eFCgUmytQWL6umtsCh
)
[href] => https://api.spotify.com/v1/albums/6fG2eFCgUmytQWL6umtsCh
[id] => 6fG2eFCgUmytQWL6umtsCh
[images] => Array
(
[0] => Array
(
[height] => 640
[url] => https://i.scdn.co/image/ab67616d0000b27387d20b9a27d5e14d74b5cb77
[width] => 640
)
[1] => Array
(
[height] => 300
[url] => https://i.scdn.co/image/ab67616d00001e0287d20b9a27d5e14d74b5cb77
[width] => 300
)
[2] => Array
(
[height] => 64
[url] => https://i.scdn.co/image/ab67616d0000485187d20b9a27d5e14d74b5cb77
[width] => 64
)
)
[name] => Carpe Diem
[release_date] => 2020-10-07
[release_date_precision] => day
[total_tracks] => 12
[type] => album
[uri] => spotify:album:6fG2eFCgUmytQWL6umtsCh
)
[artists] => Array
(
[0] => Array
(
[external_urls] => Array
(
[spotify] => https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr
)
[href] => https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr
[id] => 4ovtyvs7j1jSmwhkBGHqSr
[name] => Olamide
[type] => artist
[uri] => spotify:artist:4ovtyvs7j1jSmwhkBGHqSr
)
[1] => Array
(
[external_urls] => Array
(
[spotify] => https://open.spotify.com/artist/68R39izwNAztATrXMOqkJS
)
[href] => https://api.spotify.com/v1/artists/68R39izwNAztATrXMOqkJS
[id] => 68R39izwNAztATrXMOqkJS
[name] => Bad Boy Timz
[type] => artist
[uri] => spotify:artist:68R39izwNAztATrXMOqkJS
)
)
[disc_number] => 1
[duration_ms] => 194000
[explicit] => 1
[external_ids] => Array
(
[isrc] => USUYG1330809
)
[external_urls] => Array
(
[spotify] => https://open.spotify.com/track/558ULLj8yY2vT8XGtgY0q9
)
[href] => https://api.spotify.com/v1/tracks/558ULLj8yY2vT8XGtgY0q9
[id] => 558ULLj8yY2vT8XGtgY0q9
[is_local] =>
[is_playable] => 1
[name] => Loading (feat. Bad Boy Timz)
[popularity] => 64
[preview_url] => https://p.scdn.co/mp3-preview/7848a9f9ea879e6b1c6618508354e2559678aa8c?cid=756f211306ad4c9a934d07c5722790b5
[track_number] => 10
[type] => track
[uri] => spotify:track:558ULLj8yY2vT8XGtgY0q9
)
I would approach it like this:
$api = array (
'tracks' =>
array (
0 =>
array (
'album' =>
array (
'album_type' => 'album',
'artists' =>
array (
0 =>
array (
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr',
),
'href' => 'https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr',
'id' => '4ovtyvs7j1jSmwhkBGHqSr',
'name' => 'Olamide',
'type' => 'artist',
'uri' => 'spotify:artist:4ovtyvs7j1jSmwhkBGHqSr',
),
),
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/album/6fG2eFCgUmytQWL6umtsCh',
),
'href' => 'https://api.spotify.com/v1/albums/6fG2eFCgUmytQWL6umtsCh',
'id' => '6fG2eFCgUmytQWL6umtsCh',
'images' =>
array (
0 =>
array (
'height' => '640',
'url' => 'https://i.scdn.co/image/ab67616d0000b27387d20b9a27d5e14d74b5cb77',
'width' => '640',
),
1 =>
array (
'height' => '300',
'url' => 'https://i.scdn.co/image/ab67616d00001e0287d20b9a27d5e14d74b5cb77',
'width' => '300',
),
2 =>
array (
'height' => '64',
'url' => 'https://i.scdn.co/image/ab67616d0000485187d20b9a27d5e14d74b5cb77',
'width' => '64',
),
),
'name' => 'Carpe Diem',
'release_date' => '2020-10-07',
'release_date_precision' => 'day',
'total_tracks' => '12',
'type' => 'album',
'uri' => 'spotify:album:6fG2eFCgUmytQWL6umtsCh',
),
'artists' =>
array (
0 =>
array (
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr',
),
'href' => 'https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr',
'id' => '4ovtyvs7j1jSmwhkBGHqSr',
'name' => 'Olamide',
'type' => 'artist',
'uri' => 'spotify:artist:4ovtyvs7j1jSmwhkBGHqSr',
),
1 =>
array (
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/artist/5yOvAmpIR7hVxiS6Ls5DPO',
),
'href' => 'https://api.spotify.com/v1/artists/5yOvAmpIR7hVxiS6Ls5DPO',
'id' => '5yOvAmpIR7hVxiS6Ls5DPO',
'name' => 'Omah Lay',
'type' => 'artist',
'uri' => 'spotify:artist:5yOvAmpIR7hVxiS6Ls5DPO',
),
),
'disc_number' => '1',
'duration_ms' => '171764',
'explicit' => '1',
'external_ids' =>
array (
'isrc' => 'USUYG1330802',
),
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/track/5DS9LiyEdw2zY8bM6kjjgM',
),
'href' => 'https://api.spotify.com/v1/tracks/5DS9LiyEdw2zY8bM6kjjgM',
'id' => '5DS9LiyEdw2zY8bM6kjjgM
[is_local] => ',
'is_playable' => '1',
'name' => 'Infinity (feat. Omah Lay)',
'popularity' => '73',
'preview_url' => 'https://p.scdn.co/mp3-preview/5159fa17676fc96e32db13b7680f7497d5c2f74d?cid=756f211306ad4c9a934d07c5722790b5',
'track_number' => '3',
'type' => 'track',
'uri' => 'spotify:track:5DS9LiyEdw2zY8bM6kjjgM',
),
1 =>
array (
'album' =>
array (
'album_type' => 'album',
'artists' =>
array (
0 =>
array (
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr',
),
'href' => 'https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr',
'id' => '4ovtyvs7j1jSmwhkBGHqSr',
'name' => 'Olamide',
'type' => 'artist',
'uri' => 'spotify:artist:4ovtyvs7j1jSmwhkBGHqSr',
),
),
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/album/6fG2eFCgUmytQWL6umtsCh',
),
'href' => 'https://api.spotify.com/v1/albums/6fG2eFCgUmytQWL6umtsCh',
'id' => '6fG2eFCgUmytQWL6umtsCh',
'images' =>
array (
0 =>
array (
'height' => '640',
'url' => 'https://i.scdn.co/image/ab67616d0000b27387d20b9a27d5e14d74b5cb77',
'width' => '640',
),
1 =>
array (
'height' => '300',
'url' => 'https://i.scdn.co/image/ab67616d00001e0287d20b9a27d5e14d74b5cb77',
'width' => '300',
),
2 =>
array (
'height' => '64',
'url' => 'https://i.scdn.co/image/ab67616d0000485187d20b9a27d5e14d74b5cb77',
'width' => '64',
),
),
'name' => 'Carpe Diem',
'release_date' => '2020-10-07',
'release_date_precision' => 'day',
'total_tracks' => '12',
'type' => 'album',
'uri' => 'spotify:album:6fG2eFCgUmytQWL6umtsCh',
),
'artists' =>
array (
0 =>
array (
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/artist/4ovtyvs7j1jSmwhkBGHqSr',
),
'href' => 'https://api.spotify.com/v1/artists/4ovtyvs7j1jSmwhkBGHqSr',
'id' => '4ovtyvs7j1jSmwhkBGHqSr',
'name' => 'Olamide',
'type' => 'artist',
'uri' => 'spotify:artist:4ovtyvs7j1jSmwhkBGHqSr',
),
1 =>
array (
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/artist/68R39izwNAztATrXMOqkJS',
),
'href' => 'https://api.spotify.com/v1/artists/68R39izwNAztATrXMOqkJS',
'id' => '68R39izwNAztATrXMOqkJS',
'name' => 'Bad Boy Timz',
'type' => 'artist',
'uri' => 'spotify:artist:68R39izwNAztATrXMOqkJS',
),
),
'disc_number' => '1',
'duration_ms' => '194000',
'explicit' => '1',
'external_ids' =>
array (
'isrc' => 'USUYG1330809',
),
'external_urls' =>
array (
'spotify' => 'https://open.spotify.com/track/558ULLj8yY2vT8XGtgY0q9',
),
'href' => 'https://api.spotify.com/v1/tracks/558ULLj8yY2vT8XGtgY0q9',
'id' => '558ULLj8yY2vT8XGtgY0q9
[is_local] => ',
'is_playable' => '1',
'name' => 'Loading (feat. Bad Boy Timz)',
'popularity' => '64',
'preview_url' => 'https://p.scdn.co/mp3-preview/7848a9f9ea879e6b1c6618508354e2559678aa8c?cid=756f211306ad4c9a934d07c5722790b5',
'track_number' => '10',
'type' => 'track',
'uri' => 'spotify:track:558ULLj8yY2vT8XGtgY0q9',
),
),
);
$tracks = [];
foreach ($api['tracks'] as $track) {
$_track = [
'artists' => '',
'name' => '',
'album' => '',
'image' => ''
];
$artists = [];
foreach ($track['artists'] as $artist) {
$artists[] = $artist['name'];
}
$_track['artists'] = implode(', ', $artists);
$_track['name'] = $track['name'];
$_track['album'] = $track['album']['name'];
$_track['image'] = $track['album']['images'][2]['url'];
$tracks[] = $_track;
}
var_dump($tracks);
Results in:
array(2) {
[0]=>
array(4) {
["artists"]=>
string(17) "Olamide, Omah Lay"
["name"]=>
string(25) "Infinity (feat. Omah Lay)"
["album"]=>
string(10) "Carpe Diem"
["image"]=>
string(64) "https://i.scdn.co/image/ab67616d0000485187d20b9a27d5e14d74b5cb77"
}
[1]=>
array(4) {
["artists"]=>
string(21) "Olamide, Bad Boy Timz"
["name"]=>
string(28) "Loading (feat. Bad Boy Timz)"
["album"]=>
string(10) "Carpe Diem"
["image"]=>
string(64) "https://i.scdn.co/image/ab67616d0000485187d20b9a27d5e14d74b5cb77"
}
}
This is conveniently accomplished with array_walk_recursive. It doesn't matter at what depth or position your url key/value is, it will be found and iterated. As follows:
$urls = []; // For collecting URLs, passed in by reference:
array_walk_recursive($data, function($val, $key) use (&$urls) {
if($key === 'url') { // if $key is "url", add to $urls; ignore the rest.
$urls[] = $val;
}
});
Note that if you have multiple url keys at different depths/positions, they will all be added in. If you need to target a specific depth/position where multiple identical keys may exist, the solution would be a bit more complicated. In your use case this is not an issue, so I've kept it simple.
Also note that array_walk_recursive callback function is only called on the "leaves" or the final values of an array. As such, it will not be called on members that are arrays containing arrays. Non-final array members will simply be followed onward until "leaves" are found.

PHP remove multidimensional array key on multiple conditions

I have a below PHP array in which you can see category/sub-category structure based on "parent_id" & "parent" element.
Now the requirement is, on the basis of "menu_display_special = 1" condition, I want to delete that key as well as the keys which have this key's id as parent_id.
Note: If the "menu_display_special = 1" condition matches, it should remove the keys from category & sub-categories(if any) from the array.
Result should return only one array element. i.e. id = 2378
Array
(
[35] => Joomla\CMS\Menu\MenuItem Object
(
[id] => 2375
[params:protected] => Joomla\Registry\Registry Object
(
[data:protected] => stdClass Object
(
[menu_display_special] => 1
)
)
[parent_id] => 2376
[parent] =>
)
[36] => Joomla\CMS\Menu\MenuItem Object
(
[id] => 2377
[params:protected] => Joomla\Registry\Registry Object
(
[data:protected] => stdClass Object
(
)
)
[parent_id] => 2376
[parent] => 1
)
[37] => Joomla\CMS\Menu\MenuItem Object
(
[id] => 2379
[params:protected] => Joomla\Registry\Registry Object
(
[data:protected] => stdClass Object
(
[menu_display_special] => 1
)
)
[parent_id] => 2377
[parent] =>
)
[38] => Joomla\CMS\Menu\MenuItem Object
(
[id] => 2380
[params:protected] => Joomla\Registry\Registry Object
(
[data:protected] => stdClass Object
(
[menu_display_special] => 1
)
)
[parent_id] => 2377
[parent] =>
)
[39] => Joomla\CMS\Menu\MenuItem Object
(
[id] => 2381
[params:protected] => Joomla\Registry\Registry Object
(
[data:protected] => stdClass Object
(
[menu_display_special] => 1
)
)
[parent_id] => 2377
[parent] =>
)
[40] => Joomla\CMS\Menu\MenuItem Object
(
[id] => 2378
[params:protected] => Joomla\Registry\Registry Object
(
[data:protected] => stdClass Object
(
)
)
[parent_id] => 2376
[parent] =>
)
)
Code After var_export :
array (
35 =>
Joomla\CMS\Menu\MenuItem::__set_state(array(
'id' => '2375',
'params' =>
Joomla\Registry\Registry::__set_state(array(
'data' =>
stdClass::__set_state(array(
'menu_display_special' => '1',
)),
)),
'parent_id' => '2376',
'parent' => false,
)),
36 =>
Joomla\CMS\Menu\MenuItem::__set_state(array(
'id' => '2377',
'params' =>
Joomla\Registry\Registry::__set_state(array(
'data' =>
stdClass::__set_state(array(
'menu_display_special' => '1',
)),
)),
'parent_id' => '2376',
'parent' => true,
)),
37 =>
Joomla\CMS\Menu\MenuItem::__set_state(array(
'id' => '2379',
'params' =>
Joomla\Registry\Registry::__set_state(array(
'data' =>
stdClass::__set_state(array(
'menu_display_special' => '1',
)),
)),
'parent_id' => '2377',
'parent' => false,
)),
38 =>
Joomla\CMS\Menu\MenuItem::__set_state(array(
'id' => '2380',
'params' =>
Joomla\Registry\Registry::__set_state(array(
'data' =>
stdClass::__set_state(array(
'menu_display_special' => '1',
)),
)),
'parent_id' => '2377',
'parent' => false,
)),
39 =>
Joomla\CMS\Menu\MenuItem::__set_state(array(
'id' => '2381',
'params' =>
Joomla\Registry\Registry::__set_state(array(
'data' =>
stdClass::__set_state(array(
)),
)),
'parent_id' => '2377',
'parent' => false,
)),
40 =>
Joomla\CMS\Menu\MenuItem::__set_state(array(
'id' => '2378',
'params' =>
Joomla\Registry\Registry::__set_state(array(
'data' =>
stdClass::__set_state(array(
)),
)),
'parent_id' => '2376',
'parent' => false,
)),
)
Coding attempt : but it returns 2 array element i.e. 2381 & 2378. It should give me only 2378 as 2381 is child of 2377( which has menu_display_special value 1)
$listArray = array_filter($list,
function($v) use($list) {
return $v->params->get('menu_display_special') != '1' && ($v->parent == TRUE || $list[$v->parent_id]['params']['menu_display_special'] != '1');
}
);
I'm not sure if your design requirements allow me to merge the conditions in my recursive function, so I've kept them separate to try to be ultimately accurate.
There is no return value and $array is preceded by a & to make it modify the originally passed input array.
Code (Demo)
function recurse(&$array, $pid = null) {
foreach ($array as $id => $item) {
if (isset($item->params->data->menu_display_special) && $item->params->data->menu_display_special == 1) {
unset($array[$id]);
recurse($array, $item->id);
} elseif ($item->parent_id === $pid) {
unset($array[$id]);
}
}
}
$list = [
35 => (object)[
'id' => '2375',
'params' => (object)[
'data' => (object)[
'menu_display_special' => '1'
]
],
'parent_id' => '2376',
'parent' => false
],
36 => (object)[
'id' => '2377',
'params' => (object)[
'data' => (object)[
'menu_display_special' => '1'
]
],
'parent_id' => '2376',
'parent' => false
],
37 => (object)[
'id' => '2379',
'params' => (object)[
'data' => (object)[
'menu_display_special' => '1'
]
],
'parent_id' => '2377',
'parent' => false
],
38 => (object)[
'id' => '2380',
'params' => (object)[
'data' => (object)[
'menu_display_special' => '1'
]
],
'parent_id' => '2377',
'parent' => false
],
39 => (object)[
'id' => '2381',
'params' => (object)[
'data' => (object)[]
],
'parent_id' => '2377',
'parent' => false
],
40 => (object)[
'id' => '2378',
'params' => (object)[
'data' => (object)[]
],
'parent_id' => '2376',
'parent' => false
],
];
recurse($list);
var_export($list);
Output:
array (
40 =>
(object) array(
'id' => '2378',
'params' =>
(object) array(
'data' =>
(object) array(
),
),
'parent_id' => '2376',
'parent' => false,
),
)

How would I return minimum value in Array of Std Class Objects (PHP)?

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);

PHP: Filtering multidimensional arrays

I'm trying to filter the following multidimentional array:
Array (
[0] => stdClass Object ( [term_id] => 5 [name] => Freelance [slug] => freelance-category1 [term_group] => 0 [term_taxonomy_id] => 5 [taxonomy] => job_listing_type [description] => [parent] => 0 [count] => 0 )
[1] => stdClass Object ( [term_id] => 2 [name] => Full Time [slug] => full-time-category2 [term_group] => 0 [term_taxonomy_id] => 2 [taxonomy] => job_listing_type [description] => [parent] => 0 [count] => 0 )
[2] => stdClass Object ( [term_id] => 6 [name] => Internship [slug] => internship-category1 [term_group] => 0 [term_taxonomy_id] => 6 [taxonomy] => job_listing_type [description] => [parent] => 0 [count] => 0 )
[3] => stdClass Object ( [term_id] => 3 [name] => Parta Time [slug] => part-time-category2 [term_group] => 0 [term_taxonomy_id] => 3 [taxonomy] => job_listing_type [description] => [parent] => 0 [count] => 0 )
[4] => stdClass Object ( [term_id] => 4 [name] => Temporary [slug] => temporary-category1 [term_group] => 0 [term_taxonomy_id] => 4 [taxonomy] => job_listing_type [description] => [parent] => 0 [count] => 0 ) )
I want to filter each item where [slug] => something-category1 into a different array and [slug] => something-category2 into a different array. The criteria for filtering is the ending part after the hip-fun.
Any help would be appreciated.
There is nothing fancy to advise here. Just iterate the array of objects, isolate the target substring in the slug value, then route any qualifying objects to their respective new group.
Code: (Demo)
$cat1 = [];
$cat2 = [];
foreach ($objects as $object) {
if ($dash = strrpos($object->slug, '-')) { // don't need to check for false-vs-0 due to task logic
$cat = substr($object->slug, ++$dash); // or $dash + 1 ...same thing
if ($cat == 'category1') {
$cat1[] = $object;
} elseif ($cat == 'category2') {
$cat2[] = $object;
}
}
}
echo "Category1 : ";
var_export($cat1);
echo "\n---\n";
echo "Category2 : ";
var_export($cat2);
Output:
Category1 : array (
0 =>
(object) array(
'term_id' => 5,
'name' => 'Freelance',
'slug' => 'freelance-category1',
'term_group' => 0,
'term_taxonomy_id' => 5,
'taxonomy' => 'job_listing_type',
'description' => NULL,
'parent' => 0,
'count' => 0,
),
1 =>
(object) array(
'term_id' => 6,
'name' => 'Internship',
'slug' => 'internship-category1',
'term_group' => 0,
'term_taxonomy_id' => 6,
'taxonomy' => 'job_listing_type',
'description' => NULL,
'parent' => 0,
'count' => 0,
),
2 =>
(object) array(
'term_id' => 4,
'name' => 'Temporary',
'slug' => 'temporary-category1',
'term_group' => 0,
'term_taxonomy_id' => 4,
'taxonomy' => 'job_listing_type',
'description' => NULL,
'parent' => 0,
'count' => 0,
),
)
---
Category2 : array (
0 =>
(object) array(
'term_id' => 2,
'name' => 'Full Time',
'slug' => 'full-time-category2',
'term_group' => 0,
'term_taxonomy_id' => 2,
'taxonomy' => 'job_listing_type',
'description' => NULL,
'parent' => 0,
'count' => 0,
),
1 =>
(object) array(
'term_id' => 3,
'name' => 'Parta Time',
'slug' => 'part-time-category2',
'term_group' => 0,
'term_taxonomy_id' => 3,
'taxonomy' => 'job_listing_type',
'description' => NULL,
'parent' => 0,
'count' => 0,
),
)

PHP tree array remove levels

I have an "tree" array like the following. This is a navigation. Now i want to remove all levels >= 3. So i only want to get an array with the first two levels. Is there a way to trim/shorten the array like that.
Do you have a hint for me what i can look for?
Array
(
[0] => Array
(
[name] => Home
[level] => 1
[sub] =>
)
[1] => Array
(
[name] => Products
[level] => 1
[sub] => Array
(
[56] => Array
(
[name] => Product 1
[level] => 2
[sub] => Array
(
[61] => Array
(
[name] => Product 1b
[target] =>
[level] => 3
[sub] =>
)
)
)
[57] => Array
(
[name] => Product 2
[level] => 2
[sub] =>
)
)
)
[2] => Array
(
[name] => Contact
[level] => 1
[sub] =>
)
[3] => Array
(
[name] => Something Else
[level] => 1
[sub] =>
)
)
$data = [
0 => ['name' => 'Home', 'level' => 1, 'sub' => []],
1 => [
'name' => 'Products',
'level' => 2,
'sub' => [
'56' => [
'name' => 'Product 1',
'level' => 2,
'sub' => [
'61' => [ 'name' => 'Product 1b', 'target' => '', 'level' => 3, 'sub' => ''],
],
],
'57' => ['name' => 'Product 2', 'level' => 2, 'sub' => '']
]
],
2 => ['name' => 'Contact', 'level' => 1, 'sub' => []],
3 => ['name' => 'Something Else', 'level' => 1, 'sub' => []]
];
function processArray(&$arr) {
foreach ($arr as $key => $array) {
if ($array['level'] >= 3) {
unset($arr[$key]);
}
if (!empty($arr[$key]['sub'])) {
processArray($arr[$key]['sub']);
}
}
}
processArray($data);

Categories