[英]Filter JSON data with recursive parent-child relationship
我有一个 JSON 父子递归结构,如下例所示。
如何过滤此 JSON 列表以仅排除与选定索引对应的对象?
familyTree =[
{
name: "parent",
index:"0",
age:"50,
children: [
{
name: "first child",
index:"0.0",
age:"30",
children: [
{
name: "first grandChild",
index:"0.0.0",
age:"5"
},
{
name: "second grandChild",
index: "0.0.1",
age:"2"
}
]
},
{
name: "second child",
index:"0.1",
age:"24",
}
]
}
]
例如,如果我想排除索引为 "0.0.1" 的元素,我的结果将是:
familyTree =[
{
name: "parent",
index:"0",
children: [
{
name: "first child",
index:"0.0",
age:"30",
children: [
{
name: "first grandChild",
index:"0.0.0",
age:"5"
}
]
},
{
name: "second child",
index:"0.1",
age:"24",
}
]
}
]
我尝试使用 ES6 函数 filter() 但它可能是错误的使用,因为它不起作用
const elemToRemove= familyTree[0].children[0].children[1]; //index: 0.0.1
familyTree.filter(
(elem) => JSON.stringify(elem) === JSON.stringify(elemToRemove)
);
感谢您的帮助
这是解决您问题的方法。 函数familyTreeFilterChildrenByIndex
检查每个元素的索引,并在任何子元素上运行它自己。
const familyTree =[ { name: "parent", index:"0", age:"50", children: [ { name: "first child", index:"0.0", age:"30", children: [ { name: "first grandChild", index:"0.0.0", age:"5" }, { name: "second grandChild", index: "0.0.1", age:"2" } ] }, { name: "second child", index:"0.1", age:"24", } ] } ] const familyTreeFilterChildrenByIndex = function (familyTree, indexToRemove) { const result = [] for (const parent of familyTree) { if (parent.index === indexToRemove) { continue } else if (parent.children) { result.push({ ...parent, children: familyTreeFilterChildrenByIndex(parent.children, indexToRemove), }) } else { result.push(parent) } } return result } console.log((familyTreeFilterChildrenByIndex(familyTree, '0.0.1')))
这是filterRec
的一种可能实现 -
function filterRec (t, f)
{ const many = (t = []) =>
t.flatMap(one)
const one = (t = {}) =>
Boolean(f(t))
? [ { ...t, children: many(t.children) } ]
: []
return many(t)
}
用法类似于Array.prototype.filter
-
const result =
filterRec(familyTree, elem => elem.index !== "0.0.1")
console.log(JSON.stringify(result, null, 2))
[
{
"name": "parent",
"index": "0",
"age": "50",
"children": [
{
"name": "first child",
"index": "0.0",
"age": "30",
"children": [
{
"name": "first grandChild",
"index": "0.0.0",
"age": "5",
"children": []
}
]
},
{
"name": "second child",
"index": "0.1",
"age": "24",
"children": []
}
]
}
]
展开下面的代码段以在您自己的浏览器中验证结果 -
function filterRec (t, f) { const many = (t = []) => t.flatMap(one) const one = (t = {}) => Boolean(f(t)) ? [ { ...t, children: many(t.children) } ] : [] return many(t) } const familyTree = [{name:"parent",index:"0",age:"50",children:[{name:"first child",index:"0.0",age:"30",children:[{name:"first grandChild",index:"0.0.0",age:"5"},{name:"second grandChild",index:"0.0.1",age:"2"}]},{name:"second child",index:"0.1",age:"24"}]}] const result = filterRec(familyTree, elem => elem.index !== "0.0.1") console.log(JSON.stringify(result, null, 2))
如果您总是通过索引访问/删除元素,您可以将其用作地址来访问该项目并在删除它的同时返回它。 此解决方案会就地编辑原始数组。
const indexToRemove = '0.0.1';
const keys = indexToRemove.split('.').map((e, i, a) => a.slice(0, i+1).join('.'));
// ['0', '0.0', '0.0.1']
const removedItem = keys.reduce((a, k, i) => {
if (i !== keys.length-1) {
a = a.find(e => e.index === k).children;
} else {
const ri = a.map(e => e.index).indexOf(k);
a = a.splice(ri, 1);
}
return a;
}, familyTree);
const familyTree =[ { name: "parent", index:"0", age:"50", children: [ { name: "first child", index:"0.0", age:"30", children: [ { name: "first grandChild", index:"0.0.0", age:"5" }, { name: "second grandChild", index: "0.0.1", age:"2" } ] }, { name: "second child", index:"0.1", age:"24", } ] } ] const indexToRemove = '0.0.1'; const keys = indexToRemove.split('.').map((e, i, a) => a.slice(0, i+1).join('.')); const removedItem = keys.reduce((a, k, i) => { if (i !== keys.length-1) { a = a.find(e => e.index === k).children; } else { const ri = a.map(e => e.index).indexOf(k); a = a.splice(ri, 1); } return a; }, familyTree); console.log(removedItem); console.log(familyTree);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.