簡體   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