嵌套数组过滤,有更优雅的方法吗?

4
我正在尝试基于搜索字符串筛选一个嵌套的结构体。
如果一个项目中有匹配的搜索字符串,那么我希望保留该项目以及其父级在该结构体中。
如果未找到搜索字符串,并且该项目没有子项,则可以将其排除。
我已经编写了一些代码,使用递归数组过滤器来检查每个项目的子项。

const data = {
  id: '0.1',
  children: [
    {
      children: [],
      id: '1.1'
    },
    {
      id: '1.2',
      children: [
        {
          children: [],
          id: '2.1'
        },
        {
          id: '2.2',
          children: [
            {
              id: '3.1',
              children: []
            },
            {
              id: '3.2',
              children: []
            },
            {
              id: '3.3',
              children: []
            }
          ]
        },
        {
          children: [],
          id: '2.3'
        }
      ]
    }
  ]
};


const searchString = '3.3';

const filterChildren = (item) => {
  if (item.children.length) {
    item.children = item.children.filter(filterChildren);
    return item.children.length;
  }
  return item.id.includes(searchString);
};


data.children = data.children.filter(filterChildren);

console.log(data);

/*This outputs:
{
  "id": "0.1",
  "children": [
    {
      "id": "1.2",
      "children": [
        {
          "id": "2.2",
          "children": [
            {
              "id": "3.3",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}*/

我担心如果我的数据结构变得非常庞大,这种方法就不太有效。

有没有一种更好的方式实现这个功能,能够限制循环次数?我在想可能可以使用reducer/transducer或类似令人兴奋的东西 :)


递归是在任意嵌套级别迭代的唯一方法。 - hindmost
@hindmost,你把“the simplest way”拼错成了“_the only way_”;) - Teemu
@hindmost 嵌套循环实际上并不是递归的,而且这个任务也可以使用嵌套循环完成。 - Teemu
@NinaScholz 在我的实际实现中,我已经创建了数据的深拷贝,以便可以进行变异。如果有一种解决方案可以在构建新结构的同时进行,那将是更可取的。 - iamalismith
1
@hindmost 我相信你可以始终使用循环和栈来替换递归结构。 - Cat
显示剩余5条评论
1个回答

0

一个搜索子元素的非变异版本。

function find(array, id) {
    var child,
        result = array.find(o => o.id === id || (child = find(o.children, id)));

    return child
        ? Object.assign({}, result, { children: [child] })
        : result;            
}

const
    data = { id: '0.1', children: [{ children: [], id: '1.1' }, { id: '1.2', children: [{ children: [], id: '2.1' }, { id: '2.2', children: [{ id: '3.1', children: [] }, { id: '3.2', children: [] }, { id: '3.3', children: [] }] }, { children: [], id: '2.3' }] }] },
    searchString = '3.3',
    result = find([data], searchString);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


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