亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Javascript - 遞歸地從樹中刪除某種類型的節點,但重新附加并傳播符合條件的子節點

Javascript - 遞歸地從樹中刪除某種類型的節點,但重新附加并傳播符合條件的子節點

寶慕林4294392 2023-02-17 16:46:44
我正在 JSON 樹上編寫遞歸函數{name, type, [children]}以刪除特定類型的節點。但是,如果已移除節點的子節點不是要移除的類型,則它們應該重新附加到父節點。我遇到了以下困難:假設我想刪除以下樹上的類型 b:const sampleData = [{name: "parent",type: "a",children: [{    name: "childA",    type: "a",    children: null    },{    name: "childB",    type: "b",    children: [{        name: "grandChildA",        type: "a",        children: null        },{        name: "grandChildB",        type: "a",        children: null        }]    },{    name: "childC",    type: "a",    children: null    }]}]parent 的原始 children 是[childA, childB, childC]. 移除后,父母應該有孩子[childA, grandChildA, grandChildB, childC]。但是,我得到的結果是[childA, [grandChildA, grandChildB], childC].我知道我需要把它分散開來,但我不確定在回避中在哪里做。這是我現在擁有的功能(我知道我在錯誤的地方使用了擴展語法):const removeType = (node, type) => {    //if the node should not be removed        if (node.type !== type){        //if the node has children, recursively call to prune children        if (node.children && node.children.length > 0){            node.children = [...node.children.map(child => removeType(child, type))                                             .filter(child => child !== null)]            return node        }        //if the node has no children, return the node        else return node    }    //if the node should be removed    else if (node.type === type){        //if the node has children, recursively call, then reattach the children        if (node.children && node.children.length > 0){            node.children = [...node.children.map(child => removeType(child, type))                                             .filter(child => child !== null)]            return node.children        }        //        else return null    }}
查看完整描述

3 回答

?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

更新


我想你可以為此使用 reduce,我現在沒有電腦來測試它,但它會是這樣的


const removeType = (node, type) => {

   if (node === null) {

     return null;

   } else {

    return node.reduce((acc, child) => {

      if(child["type"] === type) {

        const removedChild = removeType(child["children"], type);

        acc = [...acc, ...removedChild];

      } else {

        child.children = removeType(child["children"], type);

        acc.push(child);

      }

      return acc;

    }, []);

  }

}

第二次更新


代碼減少:


const removeType = (node, type) => {

    if (!node) return;


    return node.reduce((acc, child) => {

        if(child["type"] === type) {

            const removedChild = removeType(child["children"], type);

            acc = [...acc, ...removedChild];

        } else {

            child.children = removeType(child["children"], type);

            acc.push(child);

        }

        return acc;

    }, []);


}


查看完整回答
反對 回復 2023-02-17
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

我認為這個答案與提供的其他答案完全不同,可以將其添加為替代方案。它具有與 Thankyou 的答案相同的遞歸結構,但它簡化了假設,即您的輸入始終是一個數組,所有非零children節點也是如此。


const removeType = (node, target) =>

  node .flatMap (({type, children, ...rest}) =>

    type === target

      ? children ? removeType (children, target) : []

      : [{...rest, type, children: children && (removeType (children, target))}]

  )


const sampleData = [{name: "parent", type: "a", children: [{name: "childA", type: "a", children: null},{name: "childB", type: "b", children: [{name: "grandChildA", type: "a", children: null},{name: "grandChildB", type: "a", children: null}]}, {name: "childC", type: "a", children: null}]}]


console .log (

 removeType (sampleData, 'b')

)

.as-console-wrapper {min-height: 100% !important; top: 0}


查看完整回答
反對 回復 2023-02-17
?
猛跑小豬

TA貢獻1858條經驗 獲得超8個贊

Array.prototype.flatMap這是使用、一些數學歸納法和一些相互遞歸來簡化程序的方法-

  • removeType接受一個數組nodes和一個要刪除的查詢類型,q

  • removeType1接受單個 node和要刪除的查詢類型,q

const removeType = (nodes, q) =>

  (nodes || []).flatMap(n => removeType1(n, q))  // <-- removeType1


const removeType1 = (node, q) =>

  q === node.type

    ? removeType(node.children)                  // <-- removeType

    : { ...node, children: removeType(node.children, q) } // <-- removeType


const input = 

  [{name:"parent",type:"a",children:[{name:"childA",type:"a",children:null},{name:"childB",type:"b",children:[{name:"grandChildA",type:"a",children:null},{name:"grandChildB",type:"a",children:null}]},{name:"childC",type:"a",children:null}]}]

  

const result =

  removeType(input, "b")


console.log(result)

輸出 -


[

  {

    "name": "parent",

    "type": "a",

    "children": [

      {

        "name": "childA",

        "type": "a",

        "children": []

      },

      {

        "name": "grandChildA",

        "type": "a",

        "children": []

      },

      {

        "name": "grandChildB",

        "type": "a",

        "children": []

      },

      {

        "name": "childC",

        "type": "a",

        "children": []

      }

    ]

  }

]

請注意,這result是一個新對象,input不會因調用.removeType


相互遞歸非常適合解決上述問題,但如果您真的只想要一個函數怎么辦?


const removeType = (t, q) =>

  Array.isArray(t)                             // <-- array

    ? t.flatMap(node => removeType(node, q))

: Object(t) === t                              // <-- object (node)

    ? q === t.type

        ? removeType(t.children, q)

        : { ...t, children: removeType(t.children, q) }

: t                                            // <-- else (no operation)


const input = 

  [{name:"parent",type:"a",children:[{name:"childA",type:"a",children:null},{name:"childB",type:"b",children:[{name:"grandChildA",type:"a",children:null},{name:"grandChildB",type:"a",children:null}]},{name:"childC",type:"a",children:null}]}]

  

const result =

  removeType(input, "b")


console.log(result)


輸出大部分是相同的,除了注意這個是如何保存的children: null。我們的原始程序產生更正確的children: []-


[

  {

    "name": "parent",

    "type": "a",

    "children": [

      {

        "name": "childA",

        "type": "a",

        "children": null

      },

      {

        "name": "grandChildA",

        "type": "a",

        "children": null

      },

      {

        "name": "grandChildB",

        "type": "a",

        "children": null

      },

      {

        "name": "childC",

        "type": "a",

        "children": null

      }

    ]

  }

]


查看完整回答
反對 回復 2023-02-17
  • 3 回答
  • 0 關注
  • 221 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號