繁体   English   中英

如何在 Javascript 中更新深度嵌套的 object?

[英]how to update a deeply nested object in Javascript?

我有一个这种类型的 json object。

{
    "id": "001",
    "type": "A",
    "value": "aaaaa",
    "data:": {},
    "path": ["001"],
    "children": [
        {
            "id": "002",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "002"],
            "children": []
        },
        {
            "id": "003",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "003"],
            "children": [
                {
                    "id": "00001",
                    "type": "B",
                    "children": []
                }
            ]
        },
        {
            "id": "004",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "004"],
            "children": [
                {
                    "id": "005",
                    "type": "A",
                    "value": "aaaaa",
                    "data:": {},
                    "path": ["001", "004", "005"],
                    "children": []
                },{
                    "id": "005",
                    "type": "A",
                    "value": "aaaaa",
                    "data:": {},
                    "path": ["001", "004", "005"],
                    "children": [
                        {
                            "id": "00002",
                            "type": "B",
                            "children": []
                        }
                    ]
                }
            ]
        },
        {
            "id": "00003",
            "type": "B",
            "children": []
        }
    ]
}

我需要替换所有type: "B"的 object ,用这个(下面提到的)类型的 object ,我可以从 object 中得到它,它可以作为 B 类型的键嵌套在任何地方。作为嵌套的 arrays 孩子的第一个孩子或第五个孩子

{
    "id": "002",
    "type": "A",
    "value": "aaaaa",
    "data:": {},
    "children": []
},

我怎样才能做到这一点? 这可以是深度嵌套的,并且没有我们应该事先替换对象的特定位置。 所以,我需要通过整个 object 来 go 并这样做。 我应该如何完成它?

编辑

我稍微更新了问题中的代码。 每个 object 中都有一个嵌套的路径属性,类型B对象除外。 因此,当用其他 object 替换键入的 B 属性时,我还需要在其中添加路径。

例如:id 的路径:“00001”,键入 B object 应该是:[“001”,“003”,“00001”]

编辑:预期结果

{
    "id": "001",
    "type": "A",
    "value": "aaaaa",
    "data:": {},
    "path": ["001"],
    "children": [
        {
            "id": "002",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "002"],
            "children": []
        },
        {
            "id": "003",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "003"],
            "children": [
                {
                    "id": "002",
                    "type": "A",
                    "value": "aaaaa",
                    "data:": {},
                    "path": ["001", "003", "002"],
                    "children": []
                },
            ]
        },
        {
            "id": "004",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "004"],
            "children": [
                {
                    "id": "005",
                    "type": "A",
                    "value": "aaaaa",
                    "data:": {},
                    "path": ["001", "004", "005"],
                    "children": []
                },{
                    "id": "005",
                    "type": "A",
                    "value": "aaaaa",
                    "data:": {},
                    "path": ["001", "004", "005"],
                    "children": [
                        {
                            "id": "002",
                            "type": "A",
                            "value": "aaaaa",
                            "data:": {},
                            "path": ["001", "004", "005", "002"],
                            "children": []
                        }
                    ]
                }
            ]
        },
        {
            "id": "002",
            "type": "A",
            "value": "aaaaa",
            "data:": {},
            "path": ["001", "002"],
            "children": []
        }
    ]
}

如果你不介意的话。

使用cloneDeepWith克隆整个树并替换特定值。

 const data = {"id":"001","type":"A","value":"aaaaa","data:":{},"children":[{"id":"002","type":"A","value":"aaaaa","data:":{},"children":[]},{"id":"003","type":"A","value":"aaaaa","data:":{},"children":[{"id":"00001","type":"B","children":[]}]},{"id":"004","type":"A","value":"aaaaa","data:":{},"children":[{"id":"005","type":"A","value":"aaaaa","data:":{},"children":[]},{"id":"005","type":"A","value":"aaaaa","data:":{},"children":[{"id":"00002","type":"B","children":[]}]}]},{"id":"00003","type":"B","children":[]}]}; const result = _.cloneDeepWith(data, (value) => { const newObj = {"id": "002", "type": "A", "value": "---NEW VALUE FOR 'B' TYPE---", "data:": {} }; return (value.type === 'B')? {...value, ...newObj}: _.noop(); }); console.dir(result, { depth: null } );
 .as-console-wrapper{min-height: 100%;important: top: 0}
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js" integrity="sha512-2iwCHjuj+PmdCyvb88rMOch0UcKQxVHi/gsAml1fN3eg82IDaO/cdzzeXX4iF2VzIIes7pODE1/G0ts3QBwslA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

这看起来像一个树遍历问题。 这是一种无需递归即可通过深度优先搜索处理该问题的方法。

 const data = {"id":"001","type":"A","value":"aaaaa","data:":{},"children":[{"id":"002","type":"A","value":"aaaaa","data:":{},"children":[]},{"id":"003","type":"A","value":"aaaaa","data:":{},"children":[{"id":"00001","type":"B","children":[]}]},{"id":"004","type":"A","value":"aaaaa","data:":{},"children":[{"id":"005","type":"A","value":"aaaaa","data:":{},"children":[]},{"id":"005","type":"A","value":"aaaaa","data:":{},"children":[{"id":"00002","type":"B","children":[]}]}]},{"id":"00003","type":"B","children":[]}]}; const dfs = () => { const stack = [data]; while(stack.length) { const curr = stack.pop(); // check for match on type if (curr.type === "B") { curr.type = "A"; curr.id = "002"; curr.value = "aaaaa"; curr.data = {}; } curr.children.forEach(child => { stack.push(child); }); } }; dfs(); const output = document.getElementById("output"); output.innerText = JSON.stringify(data, null, 2);
 <pre id="output" />

我在控制台中玩了这个,它做了你想要的(基于提供的 json 阵列,将所有“B”设置为“A”类型)。 这是一个递归的 function ,因此对于它在“子”数组中遇到的任何嵌套子项,它将在数组中的每个项目上再次调用 function 。


function fixObjects (obj) {
  if (obj["type"] === "B") {
    obj["type"] = "A";
    obj["id"] = "002";
    obj["value"] = "aaaaa";
    obj["data"] = {};
  } 
  if (obj["children"].length > 0) {
     obj["children"].forEach (child => fixObjects (child));
  }
}

fixObjects (_yourArray)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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