javascript – 递归过滤数组的对象

前端之家收集整理的这篇文章主要介绍了javascript – 递归过滤数组的对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
用这个打墙,以为我会把它贴在这里,以防某种灵魂碰到一个类似的灵魂.我有一些数据看起来像这样:
const input = [
  {
    value: 'Miss1',children: [
      { value: 'Miss2' },{ value: 'Hit1',children: [ { value: 'Miss3' } ] }
    ]
  },{
    value: 'Miss4',children: [
      { value: 'Miss5' },{ value: 'Miss6',children: [ { value: 'Hit2' } ] }
    ]
  },{
    value: 'Miss7',children: [
      { value: 'Miss8' },{ value: 'Miss9',children: [ { value: 'Miss10' } ] }
    ]
  },{
    value: 'Hit3',children: [
      { value: 'Miss11' },{ value: 'Miss12',children: [ { value: 'Miss13' } ] }
    ]
  },{
    value: 'Miss14',children: [
      { value: 'Hit4' },{ value: 'Miss15',children: [ { value: 'Miss16' } ] }
    ]
  },];

我不知道在运行时层次结构将会有多深,即有多少级对象将有一个子数组.我已经简化了这个例子,实际上我需要将值属性搜索项的数组进行匹配.我们现在假设我在匹配那个value.includes(‘Hit’).

我需要一个返回一个新数组的函数

>每个不具有子项的非匹配对象,或者子层次结构中没有匹配,不应该存在于输出对象中
>具有包含匹配对象的后代的每个对象都应保留
>匹配对象的所有后代应保留

在这种情况下,我正在考虑一个“匹配对象”为具有值属性的值,并且反之亦然.

输出应该如下所示:

const expected = [
  {
    value: 'Miss1',children: [
      { value: 'Hit1',children: [
      { value: 'Miss6',]
  }
];

非常感谢任何花时间阅读这篇文章的人,如果我先到达那里,就会发布我的解决方案.

解决方法

使用.filter()和进行递归调用,就像上面的评论所描述的,基本上是你需要的.您只需要在返回之前更新每个.children属性与递归调用的结果.

返回值只是生成的.children集合的.length,所以如果至少有一个,则保留对象.

var res = input.filter(function f(o) {
  if (o.value.includes("Hit")) return true

  if (o.children) {
    return (o.children = o.children.filter(f)).length
  }
})
const input = [
  {
    value: 'Miss1',];

var res = input.filter(function f(o) {
  if (o.value.includes("Hit")) return true

  if (o.children) {
    return (o.children = o.children.filter(f)).length
  }
})
console.log(JSON.stringify(res,null,2))

请注意,一个String上的.includes()是ES7,因此可能需要修复旧版浏览器.您可以使用传统的.indexOf(“Hit”)!= -1在其位置.

为了不突变原件,创建一个映射函数来复制一个对象,并在过滤器之前使用它.

function copy(o) {
  return Object.assign({},o)
}

var res = input.map(copy).filter(function f(o) {
  if (o.value.includes("Hit")) return true

  if (o.children) {
    return (o.children = o.children.map(copy).filter(f)).length
  }
})

要真正压缩代码,可以这样做:

var res = input.filter(function f(o) {
  return o.value.includes("Hit") ||
         o.children && (o.children = o.children.filter(f)).length
})

虽然它有点难以阅读.

原文链接:https://www.f2er.com/js/151424.html

猜你在找的JavaScript相关文章