I am writing a recursive function to find out the item which has the same id as I pass to the function.
As you can see that each object item has an id
property and the item also has a sub_categories
property which is an array contains some other objects or an empty array.
const arr = [
{
"id": 1013,
"code": "CAT1",
"name": {
"en": "TOP 1",
"fr": "TOP 1"
},
"_name": "TOP 1",
"level": 1,
"sub_categories": [
{
"id": 1016,
"code": "SUB1",
"name": {
"en": "Child 1",
"fr": "Child 1"
},
"_name": "Child 1",
"level": 2,
"sub_categories": [
{
"id": 1017,
"code": "SUB11",
"name": {
"en": "Child 2",
"fr": "Child 2"
},
"_name": "Child 2",
"level": 3,
"sub_categories": [
{
"id": 1018,
"code": "SUB111",
"name": {
"en": "Child 3",
"fr": "Child 3"
},
"_name": "Child 3",
"level": 4,
"sub_categories": [
{
"id": 1019,
"code": "SUB21",
"name": {
"en": "Child 4",
"fr": "Child 4"
},
"_name": "Child 4",
"level": 5,
"sub_categories": []
}
]
}
]
}
]
}
]
},
{
"id": 1014,
"code": "CAT2",
"name": {
"en": "TOP 2",
"fr": "TOP 2"
},
"_name": "TOP 2",
"level": 1,
"sub_categories": [
{
"id": 1020,
"code": "SUB22",
"name": {
"en": "Child 1",
"fr": "Child 1"
},
"_name": "Child 1",
"level": 2,
"sub_categories": []
}
]
},
{
"id": 1015,
"code": "CAT3",
"name": {
"en": "TOP 3",
"fr": "TOP 3"
},
"_name": "TOP 3",
"level": 1,
"sub_categories": []
}
]
const arrFilter = (targetId) => {
let res = null;
for(let y = 0; y < arr.length; y ) {
if (arr[y].id === targetId) {
res = arr[y];
} else if(arr[y].sub_categories.length) {
res = arrFilter(arr[y].sub_categories, targetId)
}
if(res !== null) return res;
}
}
console.log(arrFilter(1017))
When I pass the id 1017
, it throws an error said Maximum call stack size exceeded
, it seems loops infinitely. Anyone know why my code loops infinitely?
CodePudding user response:
You're using arr
in your function to search for the item, however, if you call the function for the second time, you're still using arr
.
You'll need to pass the array itself to the function so the second (recursive) time you only search that part:
const arr = [{"id": 1013, "code": "CAT1", "name": {"en": "TOP 1", "fr": "TOP 1"}, "_name": "TOP 1", "level": 1, "sub_categories": [{"id": 1016, "code": "SUB1", "name": {"en": "Child 1", "fr": "Child 1"}, "_name": "Child 1", "level": 2, "sub_categories": [{"id": 1017, "code": "SUB11", "name": {"en": "Child 2", "fr": "Child 2"}, "_name": "Child 2", "level": 3, "sub_categories": [{"id": 1018, "code": "SUB111", "name": {"en": "Child 3", "fr": "Child 3"}, "_name": "Child 3", "level": 4, "sub_categories": [{"id": 1019, "code": "SUB21", "name": {"en": "Child 4", "fr": "Child 4"}, "_name": "Child 4", "level": 5, "sub_categories": [] } ] } ] } ] } ] }, {"id": 1014, "code": "CAT2", "name": {"en": "TOP 2", "fr": "TOP 2"}, "_name": "TOP 2", "level": 1, "sub_categories": [{"id": 1020, "code": "SUB22", "name": {"en": "Child 1", "fr": "Child 1"}, "_name": "Child 1", "level": 2, "sub_categories": [] } ] }, {"id": 1015, "code": "CAT3", "name": {"en": "TOP 3", "fr": "TOP 3"}, "_name": "TOP 3", "level": 1, "sub_categories": [] } ];
const arrFilter = (search, targetId) => {
let res = null;
for (let y = 0; y < search.length; y ) {
if (search[y].id === targetId) {
res = search[y];
} else if(search[y].sub_categories.length) {
res = arrFilter(search[y].sub_categories, targetId)
}
if(res !== null) return res;
}
}
console.log(arrFilter(arr, 1017))
Slightly improved version could look something like:
const arr = [{"id": 1013, "code": "CAT1", "name": {"en": "TOP 1", "fr": "TOP 1"}, "_name": "TOP 1", "level": 1, "sub_categories": [{"id": 1016, "code": "SUB1", "name": {"en": "Child 1", "fr": "Child 1"}, "_name": "Child 1", "level": 2, "sub_categories": [{"id": 1017, "code": "SUB11", "name": {"en": "Child 2", "fr": "Child 2"}, "_name": "Child 2", "level": 3, "sub_categories": [{"id": 1018, "code": "SUB111", "name": {"en": "Child 3", "fr": "Child 3"}, "_name": "Child 3", "level": 4, "sub_categories": [{"id": 1019, "code": "SUB21", "name": {"en": "Child 4", "fr": "Child 4"}, "_name": "Child 4", "level": 5, "sub_categories": [] } ] } ] } ] } ] }, {"id": 1014, "code": "CAT2", "name": {"en": "TOP 2", "fr": "TOP 2"}, "_name": "TOP 2", "level": 1, "sub_categories": [{"id": 1020, "code": "SUB22", "name": {"en": "Child 1", "fr": "Child 1"}, "_name": "Child 1", "level": 2, "sub_categories": [] } ] }, {"id": 1015, "code": "CAT3", "name": {"en": "TOP 3", "fr": "TOP 3"}, "_name": "TOP 3", "level": 1, "sub_categories": [] } ];
const arrFilter = (search, targetId) => {
for (const obj of search) {
if (obj.id === targetId) {
return obj;
}
if (obj.sub_categories.length > 0) {
const tmp = arrFilter(obj.sub_categories, targetId);
if (tmp) {
return tmp;
}
}
}
return false;
}
console.log(arrFilter(arr, 1014))