如何更新 Javascript 中的深层嵌套对象?

Thi*_*aja 5 javascript arrays json nested object

我有一个这种类型的 json 对象。

{
    "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": []
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我需要用这种类型的对象替换所有type: "B", ,我可以从带有 ids 作为类型 B 的键的对象中获取该类型的对象。这种类型的 B 对象可以作为第一个子对象或作为第一个子对象嵌套在任何地方嵌套子数组的第五个子数组

{
    "id": "002",
    "type": "A",
    "value": "aaaaa",
    "data:": {},
    "children": []
},
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?这可以是深层嵌套的,并且没有我们应该事先替换对象的特定位置。所以,我需要遍历整个对象并执行此操作。我应该如何完成它?

编辑

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

例如:id 的路径:“00001”,输入的 B 对象应该是:[“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": []
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

FFi*_*ire 7

洛达什如果你不介意的话。

使用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 } );
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper{min-height: 100%!important; top: 0}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

--- 更新 2---(没有 lodash)

使用局部变量来存储和组合当前路径。

const data = { "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": [] }] }

const deepReplace = (obj, prevPath = []) => {
    if (obj.type === 'A') {
      if  (obj.children.length) {
        obj.children = obj.children.map((childObj) => deepReplace(childObj, obj.path))
      }
      return obj;
    };
    if (obj.type === 'B') {
      const id = '002';
      return { id, type: "A", value: "aaaaa",  path: [...prevPath, id],  data: {}, children: []};
    };
 };

console.dir(deepReplace(data), { depth: null });
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper{min-height: 100%!important; top: 0}
Run Code Online (Sandbox Code Playgroud)