Having a senior-moment, and struggling to get a recursive method to work correctly in Javascript.
There are similar Q&A's here, though nothing I see that has helped me so far.
That being said, if there is indeed a duplicate, i will remove this question.
Given the following array of objects:
var collection = [
{
id: 1,
name: "Parent 1",
children: [
{ id: 11, name: "Child 1", children: [] },
{ id: 12, name: "Child 2", children: [] }
]
},
{
id: 2,
name: "Parent 2",
children: [
{
id: 20,
name: "Child 1",
children: [
{ id: 21, name: "Grand Child 1", children: [] },
{ id: 22, name: "Grand Child 2", children: [] }
]
}
]
},
{
id: 3,
name: "Parent 3",
children: [
{ id: 31, name: "Child 1", children: [] },
{ id: 32, name: "Child 2", children: [] }
]
},
];
I've gone through a few attempts though my method seems to return early after going through one level only.
My latest attempt is:
Can someone please point me in the right direction.
function findType(col, id) {
for (i = 0; i < col.length; i++) {
if (col[i].id == id) {
return col[i];
}
if (col[i].children.length > 0) {
return findType(col[i].children, id);
}
}
return null;
}
I am trying to find an object where a given id
matches, so looking for id 1
should return the whole object with the name Parent 1
. If looking for id 31
then the whole object with the id 31
and name Child 1
should be returned.
This would translate into
var t = findType(collection, 1);
or
var t = findType(collection, 31);
Note I would like help with a pure JavaScript solution, and not a plugin or other library. Though they may be more stable, it won't help with the learning curve. Thanks.
Having a senior-moment, and struggling to get a recursive method to work correctly in Javascript.
There are similar Q&A's here, though nothing I see that has helped me so far.
That being said, if there is indeed a duplicate, i will remove this question.
Given the following array of objects:
var collection = [
{
id: 1,
name: "Parent 1",
children: [
{ id: 11, name: "Child 1", children: [] },
{ id: 12, name: "Child 2", children: [] }
]
},
{
id: 2,
name: "Parent 2",
children: [
{
id: 20,
name: "Child 1",
children: [
{ id: 21, name: "Grand Child 1", children: [] },
{ id: 22, name: "Grand Child 2", children: [] }
]
}
]
},
{
id: 3,
name: "Parent 3",
children: [
{ id: 31, name: "Child 1", children: [] },
{ id: 32, name: "Child 2", children: [] }
]
},
];
I've gone through a few attempts though my method seems to return early after going through one level only.
My latest attempt is:
Can someone please point me in the right direction.
function findType(col, id) {
for (i = 0; i < col.length; i++) {
if (col[i].id == id) {
return col[i];
}
if (col[i].children.length > 0) {
return findType(col[i].children, id);
}
}
return null;
}
I am trying to find an object where a given id
matches, so looking for id 1
should return the whole object with the name Parent 1
. If looking for id 31
then the whole object with the id 31
and name Child 1
should be returned.
This would translate into
var t = findType(collection, 1);
or
var t = findType(collection, 31);
Note I would like help with a pure JavaScript solution, and not a plugin or other library. Though they may be more stable, it won't help with the learning curve. Thanks.
Share Improve this question asked Feb 9, 2018 at 13:18 Darren WainwrightDarren Wainwright 30.8k22 gold badges84 silver badges131 bronze badges4 Answers
Reset to default 3You was close, you need a variable to store the temporary result of the nested call of find and if found, then break the loop by returning the found object.
Without, you return on any found children without iterating to the end of the array if not found at the first time.
function findType(col, id) {
var i, temp;
for (i = 0; i < col.length; i++) {
if (col[i].id == id) {
return col[i];
}
if (col[i].children.length > 0) {
temp = findType(col[i].children, id); // store result
if (temp) { // check
return temp; // return result
}
}
}
return null;
}
var collection = [{ id: 1, name: "Parent 1", children: [{ id: 11, name: "Child 1", children: [] }, { id: 12, name: "Child 2", children: [] }] }, { id: 2, name: "Parent 2", children: [{ id: 20, name: "Child 1", children: [{ id: 21, name: "Grand Child 1", children: [] }, { id: 22, name: "Grand Child 2", children: [] }] }] }, { id: 3, name: "Parent 3", children: [{ id: 31, name: "Child 1", children: [] }, { id: 32, name: "Child 2", children: [] }] }];
console.log(findType(collection, 31));
console.log(findType(collection, 1));
.as-console-wrapper { max-height: 100% !important; top: 0; }
const findType = (ar, id) => {
return ar.find(item => {
if (item.id === id) {
return item;
}
return item.children.find(cItem => cItem.id === id)
})
}
I think this suffice your needs
You need to ask for the "found" object
let found = findType(col[i].children, id);
if (found) {
return found;
}
Look at this code snippet
var collection = [{ id: 1, name: "Parent 1", children: [{ id: 11, name: "Child 1", children: [] }, { id: 12, name: "Child 2", children: [] } ] }, { id: 2, name: "Parent 2", children: [{ id: 20, name: "Child 1", children: [{ id: 21, name: "Grand Child 1", children: [] }, { id: 22, name: "Grand Child 2", children: [] } ] }] }, { id: 3, name: "Parent 3", children: [{ id: 31, name: "Child 1", children: [] }, { id: 32, name: "Child 2", children: [] } ] }];
function findType(col, id) {
for (let i = 0; i < col.length; i++) {
if (col[i].id == id) {
return col[i];
}
if (col[i].children.length > 0) {
let found = findType(col[i].children, id);
if (found) {
return found;
}
}
}
return null;
}
var t = findType(collection, 31);
console.log(t);
.as-console-wrapper {
max-height: 100% !important
}
1.
Actually your function findType
return the value null for every id
parameter at the node
{ id: 11, name: "Child 1", children: [] }
When you hit return, it stops all the recursion.
You have to check the return value from the nested call of findType
function.
2.
Your for
loop should looke like
for (let i = 0; i < col.length; i++)
instead of
for (i = 0; i < col.length; i++)
Because without the let you share a same variable i in the nested call of the function findType
and the value will be changed for the dad calling function.
The function could be :
function findType(col, id) {
for (let i = 0; i < col.length; i++) {
if (col[i].id == id) {
return col[i];
}
var nested = findType(col[i].children, id);
if (nested) return nested;
}
return null;
}