I have array of categories which has inside many subcategories, each sub categories have their sub categories and so on ...
array(1) {
["categories"]=>array(11) {
[0]=>array(4) {
["id"]=>int(368)
["name"]=>string(8) "Aksesuar"
["parentId"]=>NULL
["subCategories"]=>array(15) {
[0]=>
array(4) {
["id"]=>
int(387)
["name"]=>
string(4) "Saat"
["parentId"]=>
int(368)
["subCategories"]=>
array(0) {
}
}
[1]=>
array(4) {
["id"]=>
int(394)
["name"]=>
string(6) "Şapka"
["parentId"]=>
int(368)
["subCategories"]=>
array(0) {
}
}
[2]=>
array(4) {
["id"]=>
int(396)
["name"]=>
string(17) "Takı & Mücevher"
["parentId"]=>
int(368)
["subCategories"]=>
array(17) {
[0]=>
array(4) {
["id"]=>
int(397)
["name"]=>
string(8) "Bileklik"
["parentId"]=>
int(396)
["subCategories"]=>
array(7) {
[0]=>
array(4) {
["id"]=>
int(1238)
["name"]=>
string(15) "Altın Bileklik"
["parentId"]=>
int(397)
["subCategories"]=>
array(0) {
}
}
Each of this subcategories have parentId which indicates parent category,Most top parent category has parent id null. I need a recursive function which I will give parameters as id of subcategory and array of categories, and it will return array of parent categories with it's respect subcategories.
function recursive($needle, $array, $id, $holder = [])
{
$holder = [];
foreach ($array as $key => $value) {
if ($key == $needle && $value == $id) {
$holder = array_merge($holder, $array);
}
if (is_array($value)) {
$holder = array_merge($holder, recursive($needle, $value, $id, $holder));
}
}
return $holder;
}
$res = recursive('id', $categories, 5208);
Above function just return array of parent category with its sub categories.
CodePudding user response:
I'm not entirely sure what the use of the 'holder' function variable was, since you reset it to an empty array on each call, so I removed it altogether.
function recursive(string $needle, array $categories, $id): ?array
{
foreach ($categories as $cat) {
if (array_key_exists($needle, $cat) && $cat[$needle] === $id) {
// make sure that if correct category is found,
// no subcategories will be included
unset($cat['subCategories']);
return $cat;
} else {
$subCat = recursive($needle, $cat['subCategories'], $id);
// if the $subCat is not null, it indicates the category
// with the correct id, or one of it's parent has been found
if ($subCat !== null) {
$cat['subCategories'] = $subCat;
return $cat;
}
}
}
return null;
}
It's actually not that complicated, the function returns an array if the ID was found in it or one if it's children, or NULL if nothing was found.
The function loops over the categories for the provided level, and it checks if the current level contains the provided ID. If not, it will search all subcategories. If something is found in the subcategory, it will replace the current subCategories with the returned ones and return the category itself as well.
This could be even cleaner if you'd wrap a class around a category, but this should get the job done. Please let me know if you might have any further questions.
Check out this 3v4l for a full repro case.