【问题标题】:Javascript recursive with for loop breaks the loop and does not finishes带有for循环的Javascript递归中断了循环并且没有完成
【发布时间】:2022-01-23 05:04:18
【问题描述】:

我正在编写一个递归函数,它需要在具有任何深度级别的对象数组中运行。 (如果它找到一个数组,它会在完成对象属性后运行到这个数组中)

我们的想法是在网页中创建一个通用表格,该表格可以处理任何类型的对象结构并呈现尊重其层次结构的元素。

我可以更深入任何级别,但它永远不会完成循环:

let keys = [
  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'filhos', 'netos', 'bisnetos'
];

let tempArr = [];
let counter = 0;

function renderer(arr) {
  for (let x = 0; x < arr.length; x++) {
    const currItem = arr[x];

    for (let y = 0; y < keys.length; y++) {
      const inner = currItem[keys[y]]
      if (inner instanceof Array) {
        tempArr = inner;
      }
      if (inner && !(inner instanceof Array)) {
        console.log(`renderizando ${counter} camada: `, inner);
      }

      if (y === keys.length - 1) {
        if (tempArr.length > 0) {
          const children = tempArr;
          tempArr = [];
          return renderer(children);
        } else {
          continue;
        }
      }
    }
  }

  counter++;
  console.log('counter: ', counter);
  return counter;
}

const data = [{
    a: '1st item',
    b: '2nd item',
    c: '3rd item',
    d: '4th item',
    filhos: [{
      a: 'filho 1st item',
      b: 'filho 2nd item',
      c: 'filho 3rd item',
      d: 'filho 4th item',
      netos: [{
        a: 'neto 1st item',
        b: 'neto 2nd item',
        c: 'neto 3rd item',
        d: 'neto 4th item',
        bisnetos: [{
          a: 'bisneto 1st item',
          b: 'bisneto 2nd item',
          c: 'bisneto 3rd item',
          d: 'bisneto 4th item',
          f: 'bisneto 5th item',
          g: 'bisneto 6th item',
          h: 'bisneto last item'
        }],
        f: 'neto 5th item',
        g: 'neto 6th item',
        h: 'neto last item'
      }],
      f: 'filho 5th item',
      g: 'filho 6th item',
      h: 'filho last item'
    }],
    f: '5th item',
    g: '6th item',
    h: 'last item'
  },
  {
    a: '1st item',
    b: '2nd item',
    c: '3rd item',
    d: '4th item',
    filhos: [{
      a: 'filho 1st item',
      b: 'filho 2nd item',
      c: 'filho 3rd item',
      d: 'filho 4th item',
      netos: [{
        a: 'neto 1st item',
        b: 'neto 2nd item',
        c: 'neto 3rd item',
        d: 'neto 4th item',
        bisnetos: [{
          a: 'bisneto 1st item',
          b: 'bisneto 2nd item',
          c: 'bisneto 3rd item',
          d: 'bisneto 4th item',
          f: 'bisneto 5th item',
          g: 'bisneto 6th item',
          h: 'bisneto last item'
        }],
        f: 'neto 5th item',
        g: 'neto 6th item',
        h: 'neto last item'
      }],
      f: 'filho 5th item',
      g: 'filho 6th item',
      h: 'filho last item'
    }],
    f: '5th item',
    g: '6th item',
    h: 'last item'
  },
  {
    a: '1st item',
    b: '2nd item',
    c: '3rd item',
    d: '4th item',
    filhos: [{
      a: 'filho 1st item',
      b: 'filho 2nd item',
      c: 'filho 3rd item',
      d: 'filho 4th item',
      netos: [{
        a: 'neto 1st item',
        b: 'neto 2nd item',
        c: 'neto 3rd item',
        d: 'neto 4th item',
        bisnetos: [{
          a: 'bisneto 1st item',
          b: 'bisneto 2nd item',
          c: 'bisneto 3rd item',
          d: 'bisneto 4th item',
          f: 'bisneto 5th item',
          g: 'bisneto 6th item',
          h: 'bisneto last item'
        }],
        f: 'neto 5th item',
        g: 'neto 6th item',
        h: 'neto last item'
      }],
      f: 'filho 5th item',
      g: 'filho 6th item',
      h: 'filho last item'
    }],
    f: '5th item',
    g: '6th item',
    h: 'last item'
  },
]

renderer(data);

看到它在第一个列表中的第一次迭代之后结束,而没有遇到接下来的两个对象。

有什么见解吗?

谢谢。

【问题讨论】:

  • return 退出整个函数,结束内循环和外循环。也许你只是想跳出内循环?
  • @Barmar 我删除了所有退货并且它有效。我认为递归函数中的 return 关键字需要返回到以前的调用。您要回复一个答案然后我可以标记为已接受吗?谢谢!
  • 如果递归调用的返回值为本层的返回值,则只需要返回即可。

标签: javascript arrays recursion


【解决方案1】:

在进行递归调用时不应使用return

另外,避免在递归函数中使用全局变量,这会使它们不可重入。如果您需要数据持久化和更新,请将其作为参数传递并返回值。您可以使用默认值作为初始值。

在我的重写中,我将counter 作为参数传递,然后返回更新后的值,调用者将其分配回其counter。同样,我将tempArr 作为参数传递。

let keys = [
  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'filhos', 'netos', 'bisnetos'
];

function renderer(arr, counter = 0, tempArr = []) {
  for (let x = 0; x < arr.length; x++) {
    const currItem = arr[x];

    for (let y = 0; y < keys.length; y++) {
      const inner = currItem[keys[y]]
      if (inner instanceof Array) {
        tempArr = inner;
      }
      if (inner && !(inner instanceof Array)) {
        console.log(`renderizando ${counter} camada: `, inner);
      }

      if (y === keys.length - 1) {
        if (tempArr.length > 0) {
          counter = renderer(tempArr, counter, []);
        }
      }
    }
  }

  counter++;
  console.log('counter: ', counter);
  return counter;
}

const data = [{
    a: '1st item',
    b: '2nd item',
    c: '3rd item',
    d: '4th item',
    filhos: [{
      a: 'filho 1st item',
      b: 'filho 2nd item',
      c: 'filho 3rd item',
      d: 'filho 4th item',
      netos: [{
        a: 'neto 1st item',
        b: 'neto 2nd item',
        c: 'neto 3rd item',
        d: 'neto 4th item',
        bisnetos: [{
          a: 'bisneto 1st item',
          b: 'bisneto 2nd item',
          c: 'bisneto 3rd item',
          d: 'bisneto 4th item',
          f: 'bisneto 5th item',
          g: 'bisneto 6th item',
          h: 'bisneto last item'
        }],
        f: 'neto 5th item',
        g: 'neto 6th item',
        h: 'neto last item'
      }],
      f: 'filho 5th item',
      g: 'filho 6th item',
      h: 'filho last item'
    }],
    f: '5th item',
    g: '6th item',
    h: 'last item'
  },
  {
    a: '1st item',
    b: '2nd item',
    c: '3rd item',
    d: '4th item',
    filhos: [{
      a: 'filho 1st item',
      b: 'filho 2nd item',
      c: 'filho 3rd item',
      d: 'filho 4th item',
      netos: [{
        a: 'neto 1st item',
        b: 'neto 2nd item',
        c: 'neto 3rd item',
        d: 'neto 4th item',
        bisnetos: [{
          a: 'bisneto 1st item',
          b: 'bisneto 2nd item',
          c: 'bisneto 3rd item',
          d: 'bisneto 4th item',
          f: 'bisneto 5th item',
          g: 'bisneto 6th item',
          h: 'bisneto last item'
        }],
        f: 'neto 5th item',
        g: 'neto 6th item',
        h: 'neto last item'
      }],
      f: 'filho 5th item',
      g: 'filho 6th item',
      h: 'filho last item'
    }],
    f: '5th item',
    g: '6th item',
    h: 'last item'
  },
  {
    a: '1st item',
    b: '2nd item',
    c: '3rd item',
    d: '4th item',
    filhos: [{
      a: 'filho 1st item',
      b: 'filho 2nd item',
      c: 'filho 3rd item',
      d: 'filho 4th item',
      netos: [{
        a: 'neto 1st item',
        b: 'neto 2nd item',
        c: 'neto 3rd item',
        d: 'neto 4th item',
        bisnetos: [{
          a: 'bisneto 1st item',
          b: 'bisneto 2nd item',
          c: 'bisneto 3rd item',
          d: 'bisneto 4th item',
          f: 'bisneto 5th item',
          g: 'bisneto 6th item',
          h: 'bisneto last item'
        }],
        f: 'neto 5th item',
        g: 'neto 6th item',
        h: 'neto last item'
      }],
      f: 'filho 5th item',
      g: 'filho 6th item',
      h: 'filho last item'
    }],
    f: '5th item',
    g: '6th item',
    h: 'last item'
  },
]

renderer(data);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2015-08-15
    相关资源
    最近更新 更多