JavaScript递归处理数组及其子数组

5

我有一个“老年痴呆”,并且在尝试使用Javascript编写递归方法时遇到了困难。

这里有类似的问题,但是我到目前为止没看到任何可以帮助我的解决方案。

话虽如此,如果确实有重复的问题,我将删除这个问题。

给定以下对象数组:

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

                }

我正在尝试查找一个与给定的id匹配的对象,因此查找id 1应该返回名称为Parent 1的整个对象。如果查找id 31,则应该返回具有id 31和名称Child 1的整个对象。
var t = findType(collection, 1);

或者
var t = findType(collection, 31);

注意: 我希望使用纯 JavaScript 解决方案,而不是插件或其他库。虽然它们可能更稳定,但对于学习曲线并没有帮助。谢谢。

4个回答

3
你已经接近正确,你需要一个变量来存储内部调用find的临时结果,如果找到了,则通过返回找到的对象来中断循环。
否则,如果第一次没有找到,则在任何找到的子元素上立即返回,而不是迭代到数组的末尾。

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


巴。看,这是老年痴呆了。非常感谢! - Darren Wainwright

1
const findType = (ar, id) => {
  return ar.find(item => {
    if (item.id === id) {
       return item;
    }

    return item.children.find(cItem => cItem.id === id)
  })
}

我认为这足以满足您的需求


1
您需要请求“found”对象。
let found = findType(col[i].children, id);
if (found) {
    return found;
}

看一下这段代码片段。

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
1. 实际上,您的函数findType对节点中的每个id参数返回null值。
{ id: 11, name: "Child 1", children: [] } 当您按回车键时,它会停止所有递归。
您需要检查findType函数的嵌套调用的返回值。


2. 你的for循环应该像这样写:
for (let i = 0; i < col.length; i++)
而不是
for (i = 0; i < col.length; i++)
因为如果没有使用 let,你会在函数findType的嵌套调用中共享同一个变量,并且该值将会被更改为父调用函数。


该文本的英译中为:函数可能是:
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;
 }   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接