Javascript 对多维数组应用过滤器,并返回过滤后的数据和父数组

Javascript 对多维数组应用过滤器,并返回过滤后的数据和父数组,javascript,arrays,dictionary,filter,ecmascript-6,Javascript,Arrays,Dictionary,Filter,Ecmascript 6,我有代码片段中提供的多维数组,我想用最内层数组的值过滤该数组,然后将该值与父数组一起返回。 比如说 从 如果我按“notes.txt”过滤,它应该会产生 [ { value: 'Documents', label: 'Documents', children: [ { value: 'notes.txt', label: 'notes.txt',

我有代码片段中提供的多维数组,我想用最内层数组的值过滤该数组,然后将该值与父数组一起返回。 比如说

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

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

            {
                value: 'notes.txt',
                label: 'notes.txt',
            }
        ]
]
这是我尝试过的,但它只返回最里面的过滤内容

const节点=[
{
值:'文档',
标签:“文件”,
儿童:[
{
值:“Employee Evaluations.zip”,
标签:“Employee Evaluations.zip”,
},
{
值:“Expense Report.pdf”,
标签:“Expense Report.pdf”,
},
{
值:“notes.txt”,
标签:“notes.txt”,
},
],
},
{
价值:'照片',
标签:“照片”,
儿童:[
{
值:'nyan cat.gif',
标签:'nyan cat.gif',
},
{
值:'SpaceX Falcon9 liftoff.jpg',
标签:“SpaceX猎鹰9号升空.jpg”,
},
],
},
];
let key=“notes.txt”;
//让filtered=nodes.filter(n=>n.value==key);
让cfiltered=nodes.map(n=>n.children.filter(n1=>n1.value==key));
//console.log(过滤);

控制台日志(cfiltered)完全在我的头顶上,没有经过测试,但想法是:

  • 筛选至少有一个子节点的节点。值==键
  • 筛选每个结果节点的子节点:
它是这样的:

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 }))
也许吧

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


[编辑]添加了Object.assign,这样您也可以获得原始对象。我真的应该先测试一下;)但是你得到了jist

只是在我的头顶上,没有经过测试,但想法是:

  • 筛选至少有一个子节点的节点。值==键
  • 筛选每个结果节点的子节点:
它是这样的:

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 }))
也许吧

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


[编辑]添加了Object.assign,这样您也可以获得原始对象。我真的应该先测试一下;)但是你得到了jist

首先,
映射所有
父项
,过滤掉不匹配的子项,然后根据
子项
大小过滤中间结果

const节点=[{
值:'文档',
标签:“文件”,
儿童:[{
值:“Employee Evaluations.zip”,
标签:“Employee Evaluations.zip”,
},
{
值:“Expense Report.pdf”,
标签:“Expense Report.pdf”,
},
{
值:“notes.txt”,
标签:“notes.txt”,
},
],
},
{
价值:'照片',
标签:“照片”,
儿童:[{
值:'nyan cat.gif',
标签:'nyan cat.gif',
},
{
值:'SpaceX Falcon9 liftoff.jpg',
标签:“SpaceX猎鹰9号升空.jpg”,
},
],
},
];
let key=“notes.txt”;
const result=nodes.map(node=>({…node,
children:node.children.filter(child=>child.value==key)
})).filter(node=>node.children.length);

控制台日志(结果)
首先,
映射所有
父项
并过滤掉不匹配的子项,然后根据
子项
大小过滤中间结果

const节点=[{
值:'文档',
标签:“文件”,
儿童:[{
值:“Employee Evaluations.zip”,
标签:“Employee Evaluations.zip”,
},
{
值:“Expense Report.pdf”,
标签:“Expense Report.pdf”,
},
{
值:“notes.txt”,
标签:“notes.txt”,
},
],
},
{
价值:'照片',
标签:“照片”,
儿童:[{
值:'nyan cat.gif',
标签:'nyan cat.gif',
},
{
值:'SpaceX Falcon9 liftoff.jpg',
标签:“SpaceX猎鹰9号升空.jpg”,
},
],
},
];
let key=“notes.txt”;
const result=nodes.map(node=>({…node,
children:node.children.filter(child=>child.value==key)
})).filter(node=>node.children.length);

控制台日志(结果)我怀疑你可能有比两个更高的维度。您希望将其视为一个树问题。由于您关心父对象和子对象,因此可以使用深度优先搜索

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,并带有值。如果父级和子级都包含该值,它将同时返回这两个值。它将删除所有不具有该值的子项。

我怀疑您可能具有比两个更高的维度。您希望将其视为一个树问题。由于您关心父对象和子对象,因此可以使用深度优先搜索

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,并带有值。如果父级和子级都包含该值,它将同时返回这两个值。它将删除所有不具有该值的子项