admin管理员组

文章数量:1331435

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 badges
Add a ment  | 

4 Answers 4

Reset to default 3

You 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;
 }   

本文标签: Javascript Recursion on array and child arraysStack Overflow