JavaScript:根据n层嵌套属性值从数组中过滤出对象的最佳解决方案

Roh*_*dal 5 javascript arrays recursion object

要求:是否有任何最佳或简单的方法可以根据其值从包含特定属性的数组中过滤出对象,而无需递归

问题陈述:我们可以使用递归来实现这一要求,但由于数据集(对象数组)非常大,并且每个对象包含n许多嵌套对象,递归方法会导致性能问题。

这是示例模拟数据:

[{
  children: [{
    children: [{
      children: [],
      isWorking: 'yes'
    }]
  }]
}, {
  children: [],
  isWorking: 'no'
}, {
  children: [{
    children: [{
      children: [],
      isWorking: 'no'
    }]
  }]
}, {
  children: [{
    children: [],
    isWorking: 'yes'
  }]
}, ...]
Run Code Online (Sandbox Code Playgroud)
  • isWorking我想从包含嵌套属性且值为 的数组中过滤出根对象yes
  • isWorking属性仅适用于不包含子对象的对象。IEchildren: []

正如我之前所说,我可以通过递归来实现这一点,但寻找不会影响性能的最佳解决方案。

这是我尝试过的(工作解决方案):

[{
  children: [{
    children: [{
      children: [],
      isWorking: 'yes'
    }]
  }]
}, {
  children: [],
  isWorking: 'no'
}, {
  children: [{
    children: [{
      children: [],
      isWorking: 'no'
    }]
  }]
}, {
  children: [{
    children: [],
    isWorking: 'yes'
  }]
}, ...]
Run Code Online (Sandbox Code Playgroud)

Ben*_*Ben 2

下面将每个递归调用放在一个新的微任务上,从而避免堆栈崩溃。

此代码运行与您的算法相同的算法,但确保对新微任务异步进行递归调用。

在下面的代码中

我。StackOverflow 不支持顶级异步。

二. async 以启用等待的使用。

三. 异步 IIFE。

四. 你的算法。

v. 暂停继续循环,for..of直到递归调用返回的 Promise 得到解决。类似于 a .then(() => checkForOccupation(children)),意味着递归调用是在微任务上使用新的堆栈进行的,从而缓解了 JS 中深度嵌套递归调用和缺乏尾调用递归优化的问题。这会带来性能损失。

六. 调用异步 IIFE 来开始工作。

七. 调用外部异步 IIFE 以弥补 StackOverflow 缺乏顶级异步支持。

(async () => {  // i.
  const getFlags = async (arr) => {  // ii.
      const flags = []

      await (async function checkForOccupation(arr) {  // iii.
          for(const { children, isWorking } of arr) {  // iv.
              !children.length
                  ? flags.push(isWorking === 'yes') 
                  : await checkForOccupation(children)  // v.
          }
      })(arr)  // vi.

      return flags
  }

  const data = [{
    children: [{
      children: [{
        children: [],
        isWorking: 'yes'
      }]
    }]
  }, {
    children: [],
    isWorking: 'no'
  }, {
    children: [{
      children: [{
        children: [],
        isWorking: 'no'
      }]
    }]
  }, {
    children: [{
      children: [],
      isWorking: 'yes'
    }]
  }]

  const flags = await getFlags(data)
  console.log(data.filter((_, index) => flags[index]))
})()
Run Code Online (Sandbox Code Playgroud)

另一种方法是显式管理状态堆栈,这将是一件苦差事。