使用es6 +(js)迭代嵌套对象并按值获取obj

时间:2019-03-03 22:05:41

标签: javascript recursion

对于这种结构的对象:

const myObj = {
  id: 1,
  name: '1',
  children: [
    {
      id: 2,
      name: '2',
      children: [
        {
          id: 3,
          name: '3',
          children: []
        }
      ]
    },
    {
      id: 4,
      name: '4',
      children: [
        {
          id: 5,
          name: '5',
          children: [
            {
              id: 6,
              name: '6',
              children: [
                {
                  id: 7,
                  name: '7',
                  children: []
                }
              ]
            }
          ]
        }
      ]
    },
  ]
}

如何通过值(id)获取对象?所以我正在寻找一个函数,如果我调用它:

findObj(myObj, 6);

它将返回以下内容:

       {
          id: 6,
          name: '6',
          children: [
            {
              id: 7,
              name: '7',
              children: []
            }
          ]
        }

另一个例子:

findObj(myObj, 3);

将返回此:

    {
      id: 3,
      name: '3',
      children: []
    }

我知道我需要递归函数。这是我到目前为止的内容:

  findObj(obj, id) {
    if (obj.id === id) {
      return obj;
    }

    obj.forEach(x => {
      if (x.id === id) {
        return x;
      } else {
        this.findObj(x.children, id);
      }
    });
  }

(这是一个角度类)

提前谢谢!

3 个答案:

答案 0 :(得分:4)

乍一看,我看到了一些问题。

如果函数中已经包含ob.id === id,则以后无需再次检查。另外,如果findObj是在作用域中定义的函数,与任何其他变量一样,并且不在“ class”定义中,则无需通过this来调用它,就像第一次调用一样到findObj,而无需使用this关键字。

此外,首先将对象传递给方法,然后再传递对象数组(obj.children),然后在forEach方法内检查ID,并在其中传递函数(x => { ...很重要),因此当您返回时,您将从该函数而不是主函数返回。

我已为您修复了该问题。我建议您了解正在发生的事情并从中学习,因为如果您知道自己在做什么(调试是您的主人),就不会发生。

findObj(obj, id) {
    if (obj.id === id) {
        return obj;
    }
    for (var i = 0; i < obj.children.length; i++) { // No forEach, so when we return, we actually return from findObj
        var r = findObj(obj.children[i], id); // We see if we have any return and let the "check logic" be defined on one location instead of duplicated.
        if (r) {
            return r;
        }
    }
}

答案 1 :(得分:1)

两个问题:

  • 您的return x;语句仅从forEach回调返回,而不从findObj函数返回。不要使用forEach!一个简单的for … of循环就可以了
  • 如果递归调用找到该对象并返回它,则将其忽略并继续进行迭代。检查是否得到结果并正确处理。

我想您不是在寻找完整的解决方案,所以我将其保留为练习:-)

答案 2 :(得分:1)

您可以检查物体或检查孩子。

function find(object, id) {
    var result;
    if (object.id === id) return object;
    object.children.some(o => result = find(o, id));
    return result;
}

const object = { id: 1, name: '1', children: [{ id: 2, name: '2', children: [{ id: 3, name: '3', children: [] }] }, { id: 4, name: '4', children: [{ id: 5, name: '5', children: [{ id: 6, name: '6', children: [{ id: 7, name: '7', children: [] }] }] }] }] };

console.log(find(object, 5));
console.log(find(object, 6));
.as-console-wrapper { max-height: 100% !important; top: 0; }