Javascript 对多维数组应用过滤器,并返回过滤后的数据和父数组
我有代码片段中提供的多维数组,我想用最内层数组的值过滤该数组,然后将该值与父数组一起返回。 比如说 从 如果我按“notes.txt”过滤,它应该会产生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',
[
{
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,并带有值。如果父级和子级都包含该值,它将同时返回这两个值。它将删除所有不具有该值的子项