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

时间:2019-06-11 10:07:58

标签: javascript arrays filtering

我正在尝试基于搜索字符串来过滤嵌套结构。

如果一个项目中的搜索字符串匹配,那么我想将该项目及其父项保留在结构中。

如果未找到搜索字符串,并且该商品没有子代,则可以打折。

我有一些代码在工作,它使用递归数组过滤器检查每个项目的子项:

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": []
            }
          ]
        }
      ]
    }
  ]
}*/

我担心如果我的数据结构变得庞大,这将不会非常有效。

是否可以通过“更精细”的方式来实现,从而限制循环的进行?我在考虑使用减速器/换能器或类似的令人兴奋的方法:)

1 个答案:

答案 0 :(得分: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; }