【问题标题】:Change value in json with recursion使用递归更改 json 中的值
【发布时间】:2019-09-06 10:42:03
【问题描述】:

我正在尝试使用带有递归函数的打字稿更改 json 值。我知道如何显示所有键或值,但我不知道如何更改值。

我有这个 json 和这个代码:


var json = {
    "a" : "hello",
    "b" : "bye",
    "c" : {
        "d" : "test1",
        "e" : "test2"
    },
    "f" : {
        "g" : {
             "h" : "test3",
             "i" : "test4"
         }
    }
};

changeInJson(id: string, value: string, level: number, json: object): void {
    level = level || 0;
    for (var property in json) {
        if (typeof json[property] === 'object') {
            this.changeInJson(id, value, ++level, json[property]);
        } else {
            console.log(property);
            if(property === id) {
                //change value in json
                console.log("Yes");
            }
        }
    }
};

changeInJson("i", "changed", 0, json);
console.log(json);

在这个例子中,我知道 json 键,但实际上我需要以某种方式保存到达键“i”的所有路径,这就是我不知道该怎么做。

谢谢

【问题讨论】:

  • changeInJson("i", "changed", 0, json); 意味着什么要改变? 0 级没有i...
  • ...或者你想改变所有i,而不考虑深度?
  • 在这种情况下,我从级别 0 开始,因为我想迭代所有 json 并且当再次调用该函数时,增加级别。在这种情况下,最终目标是在不知道 'i' 的值在 f.g.i 中的情况下更改 'i' 的值
  • 看我的回答。级别在这里无关紧要,递归的终止情况是对象不再包含对象。
  • @dgalan 我想你可以在这里使用 Lodash。 lodash.com/docs/4.17.11#set

标签: json typescript loops recursion


【解决方案1】:

对于这个特定的递归任务,没有必要跟踪递归的深度(或级别),因为当所考虑的对象没有子对象时,自然会达到终止递归的情况。这里需要考虑的是,包含循环引用的对象会破坏递归,除非你 take special measures to track what you've already seen

更改名称为 id 的任何道具/嵌套道具的通用方法类似于:

const changeInJson = (id: string, value: string, obj: object): void => {
  for (const [k, v] of Object.entries(obj)) {
    if (k === id) {
      obj[k] = value;
    } else if (typeof v === "object") {
      changeInJson(id, value, v);
    }
  }
};

IIRC 你至少需要在tsconfig.json 文件中为Object.entries 提供es2017 lib

我会将添加数组处理作为练习留给读者:)

【讨论】:

  • 这里我想我理解level的用法了。考虑一个用法:``` { "a": "Test", b: { "a": "value" } } ``` 现在用户想要编辑内部a 而不是外部a . @dgalan 对吗?
  • @KushagraSaxena 我认为level 只是 OP 对递归的误解的产物。等待确认。
  • 我觉得最好用。 lodash.com/docs/4.17.11#set。你怎么看?
  • @spender 你是对的,我错了关卡。没有必要。您的代码完美运行!谢谢你们的帮助!
  • @dgalan 感谢您的确认。我更新了我的答案,并添加了一些关于 circ 引用的有趣的额外信息。
【解决方案2】:

@spender 的解决方案几乎很好,但它在 null 值上的错误...

这里是修复:

const changeInJson = (id: string, value: string, obj: object): void => {
  for (const [k, v] of Object.entries(obj)) {
    if (k === id) {
      obj[k] = value;
    } else if (v && typeof v === "object") {
      changeInJson(id, value, v);
    }
  }
};

【讨论】:

    猜你喜欢
    • 2015-02-17
    • 2018-09-18
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多