繁体   English   中英

过滤具有递归父子关系的 JSON 数据

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM