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