【问题标题】:Apply filter on multi dimensional array and return filtered data along with parent对多维数组应用过滤器并返回过滤后的数据以及父级
【发布时间】:2019-02-05 03:04:40
【问题描述】:

我有代码 sn-p 上提供的多维数组,我想用最内层数组的值过滤该数组,然后将该值与 parent 一起返回。 例如

来自

const nodes = [
    {
        value: 'Documents',
        label: 'Documents',
        children: [
            {
                value: 'Employee Evaluations.zip',
                label: 'Employee Evaluations.zip',
            },
            {
                value: 'Expense Report.pdf',
                label: 'Expense Report.pdf',
            },
            {
                value: 'notes.txt',
                label: 'notes.txt',
            },
        ],
    },
    {
        value: 'Photos',
        label: 'Photos',
        children: [
            {
                value: 'nyan-cat.gif',
                label: 'nyan-cat.gif',
            },
            {
                value: 'SpaceX Falcon9 liftoff.jpg',
                label: 'SpaceX Falcon9 liftoff.jpg',

            },
        ],
    },
]; 

如果我按“notes.txt”过滤它应该会产生

 [
    {
        value: 'Documents',
        label: 'Documents',
        children: [

            {
                value: 'notes.txt',
                label: 'notes.txt',
            }
        ]
]

这是我尝试过的,但它只返回最里面的过滤内容

const nodes = [
    {
        value: 'Documents',
        label: 'Documents',
        children: [
            {
                value: 'Employee Evaluations.zip',
                label: 'Employee Evaluations.zip',
            },
            {
                value: 'Expense Report.pdf',
                label: 'Expense Report.pdf',
            },
            {
                value: 'notes.txt',
                label: 'notes.txt',
            },
        ],
    },
    {
        value: 'Photos',
        label: 'Photos',
        children: [
            {
                value: 'nyan-cat.gif',
                label: 'nyan-cat.gif',
            },
            {
                value: 'SpaceX Falcon9 liftoff.jpg',
                label: 'SpaceX Falcon9 liftoff.jpg',
               
            },
        ],
    },
];
let key="notes.txt";
//let filtered=nodes.filter(n=>n.value===key);
let cfiltered=nodes.map(n=>n.children.filter(n1=>n1.value===key));
//console.log(filtered);
console.log(cfiltered);

【问题讨论】:

    标签: javascript arrays dictionary filter ecmascript-6


    【解决方案1】:

    首先map对所有parent进行过滤,过滤掉不匹配的孩子,然后根据children大小过滤中间结果。

    const nodes = [{
        value: 'Documents',
        label: 'Documents',
        children: [{
            value: 'Employee Evaluations.zip',
            label: 'Employee Evaluations.zip',
          },
          {
            value: 'Expense Report.pdf',
            label: 'Expense Report.pdf',
          },
          {
            value: 'notes.txt',
            label: 'notes.txt',
          },
        ],
      },
      {
        value: 'Photos',
        label: 'Photos',
        children: [{
            value: 'nyan-cat.gif',
            label: 'nyan-cat.gif',
          },
          {
            value: 'SpaceX Falcon9 liftoff.jpg',
            label: 'SpaceX Falcon9 liftoff.jpg',
    
          },
        ],
      },
    ];
    let key="notes.txt";
    const result = nodes.map(node => ({ ...node,
      children: node.children.filter(child => child.value === key)
    })).filter(node => node.children.length);
    console.log(result);

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      纯粹是在我的脑海中没有经过测试,但这个想法是:

      • 过滤至少有一个 child.value == key 的节点
      • 过滤每个结果节点的子节点:

      会是这样的:

      nodes.filter(n => n.children.reduce((cur, acc) => acc || cur.value == key, false).length > 0)
           .map(n => Object.assign(n, { children: n.children.filter(c => c.value == key }))
      

      也许?

      [编辑]添加了一个初始值来减少

      [Edit] 添加了 Object.assign,因此您也可以获得原始对象。我真的应该先测试一下;)但你明白了!

      【讨论】:

        【解决方案3】:

        我怀疑你的维度可能比两个更高。您想将此视为树问题。由于您关心父母和孩子,您可以使用深度优先搜索。

        function getNodeWithChild( accumulator, rootNode, searchValue ) {
          if (!rootNode || !rootNode.children) return accumulator;
        
          let parentNode;
          rootNode.children.forEach( child => {
             accumulator = getNodeWithChild(accumulator, child, searchValue);
             if (child.value === searchValue || child.label === searchValue) {
               if (parentNode) {
                  parentNode.children.push(child);
               } else {
                 parentNode = Object.assign({}, rootNode);
                 parentNode.children = [child];
               }
            }
            if (parentNode) {
              accumulator.push(parentNode);
            }
          }
          return accumulator
        } 
        
        // And you call it like this:
        const tree = { children: nodes } // just to simplify treat it like the same node as the rest
        const filteredNodes = getNodeWithChild( [], rootNode, 'notes.txt'); 
        

        这是一个递归版本,但可以使用队列进行迭代。它未经测试,可能需要一些调试。但它应该返回每个孩子的 parentNode 的值。如果父母和孩子都包含该值,它将并排返回。它也会删除所有没有该值的孩子。

        【讨论】:

          猜你喜欢
          • 2019-01-22
          • 1970-01-01
          • 2017-03-08
          • 2018-07-31
          • 2017-10-07
          • 1970-01-01
          • 2015-09-23
          • 2021-03-23
          • 1970-01-01
          相关资源
          最近更新 更多