嵌套数组上的递归过滤器

leo*_*rd0 6 javascript arrays recursion filter

我需要根据查询过滤一个嵌套结构,看起来像这样。我需要返回所有对象,包括与对象名称中的查询字符串匹配的子树的父对象。请帮忙,我被卡住了。

[
   {
     name: 'bob',
     type: 1,
     children: [
       {
         name: 'bob',
         type: 2,
         children: [
           {
             name: 'mike',
             type: 3,
             children: [ 
               {
                 name:'bob',
                 type: 7,
                 children: []
               },
               {
                 name: 'mike',
                 type: 9,
                 children: []
               }
             ]
           }
         ]
       },
       {
         name: 'mike',
         type: 2
       }
     ]
   }
 ]
Run Code Online (Sandbox Code Playgroud)

现在我能够递归地在树中找到匹配项,但是该函数在第一次匹配时返回对象,并且不会在同一对象的子级别上进行更深入的搜索。任何建议,我如何修改代码以递归搜索所有级别?

  return tree.map(copy).filter(function filterNested(node) {
    if (node.name.toLowerCase().indexOf(query) !== -1) {
      return true;
    }

    if (node.children) {
      return (node.children = node.children.map(copy).filter(filterNested))
        .length;
    }
  });
Run Code Online (Sandbox Code Playgroud)

如果我正在搜索查询 'bob',预期的结果应该是,

 const arr = [
   {
     name: 'bob',
     type: 1,
     children: [
       {
         name: 'bob',
         type: 2,
         children: [
           {
             name: 'mike',
             type: 3,
             children: [ 
               {
                 name:'bob',
                 type: 7
               },
  
             ]
           }
         ]
       },
     ]
   }
 ]
Run Code Online (Sandbox Code Playgroud)


Nin*_*olz 9

如果它们的长度不为零,您可以减少数组并使用可选子对象构建新对象。

function filter(array, fn) {
    return array.reduce((r, o) => {
        var children = filter(o.children || [], fn);
        if (fn(o) || children.length) r.push(Object.assign({}, o, children.length && { children }));
        return r;
    }, []);
}

var data = [{ name: 'bob', type: 1, children: [{ name: 'bob', type: 2, children: [{ name: 'mike', type: 3, children: [{ name: 'bob', type: 7 }, { name: 'same', typ: 9 }] }] }, { name: 'mike', type: 2 }] }],
    result = filter(data, ({ name }) => name.toLowerCase() === 'bob');

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