【问题标题】:Replace value while iterating through nested json file in javascript在javascript中遍历嵌套的json文件时替换值
【发布时间】:2018-01-10 20:18:13
【问题描述】:

我已经搜索了很长时间,但找不到任何解决我的问题的方法... 我得到了一个像这样的随机嵌套 json 对象:

var obj = { a: 1, b: 2, c: { a: 1, b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
someValue = 'hello';
newValue = 'bye';

现在我要搜索“someValue”。如果 'obj' 包含此值,则会触发警报。这是我的例子:

function wannaChangeValue(obj) {
    var itemKey;
    if (obj instanceof Object) {
        for (itemKey in obj) {
            if (obj.hasOwnProperty(itemKey)) {
                wannaChangeValue(obj[itemKey]);
            }
        }
    } else {
        alert(obj);
        if (obj == someValue) {
            alert('got it! now change...')
            //change someValue to newValue 
        }
    }
    return obj
}

wannaChangeValue(obj)

这很好用,但我怎样才能将“someValue”更改为“newValue”并再次返回整个 json 文件? 我已经看到了很多如何处理这个问题的例子,但是我需要一个任何类型的嵌套 json 对象的解决方案,而不知道更改这个值的路径。也许这是一个完全错误的方法...... 提前致谢!

【问题讨论】:

标签: javascript jquery json recursion


【解决方案1】:

您可以对任何找到的对象使用递归方法,再次调用该函数。

function update(object, search, replace) {
    Object.keys(object).forEach(function (k) {
        if (object[k] && typeof object[k] === 'object') {
            return update(object[k], search, replace)
        }
        if (object[k] === search) {
            object[k] = replace;
        }
    });
    
}

var object = { a: 1, b: 2, c: { a: 1, b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
    
update(object, 'hello', 'bye');

console.log(object)
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这样做的目的是什么:object[k] &&?
  • 它防止null 值被键迭代。
  • 我认为,我对@Alexandru-Ionut Mihai 的回答的评论不仅可以解决您的用例,还可以优化,因为不需要遍历没有密钥的节点树
  • 嗯。是和不是。是的,因为它缩短了迭代,不,因为每个嵌套对象的开销。
  • @HassanImam,它会阻止评估下一个 if 子句。
【解决方案2】:

您可以使用for...in 循环创建函数,如果当前值与 oldValue 匹配,则更改该值。

var obj = { a: 1, b: 2, c: { a: '1', b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
var someValue = 'hello';
var newValue = 'bye';

function changeVal(data, oldV, newV) {
  for(var i in data) {
    if(typeof data[i] == 'object') changeVal(data[i], oldV, newV);
    if(data[i] == oldV) data[i] = newV
  }
  return data
}

console.log(changeVal(obj, someValue, newValue))

【讨论】:

    【解决方案3】:

    您可以定义一个函数,通过您的对象递归搜索value,然后替换这个值。

    function replaceObj (obj, valueForSearch,valueForReplace) {
        for (var key in obj) {
            var value = obj[key];
            if (typeof value === 'object') {
                replaceObj(value, valueForSearch,valueForReplace);
            }
            if (value === valueForSearch) {
                obj[key]=valueForReplace;
            }
        }
    }
    let obj = { a: 1, b: 2, c: { a: 1, b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
    let someValue = 'hello';
    let newValue = 'bye';
    replaceObj(obj,someValue,newValue);
    console.log(obj);

    【讨论】:

    • 你甚至可以优化成typeof value === 'object' && JSON.stringify(value).indexOf(query)>=0
    【解决方案4】:

    这是一个快速的解决方案:

    function wannaChangeValue(obj) {
        var itemKey;
        if (obj instanceof Object) {
            for (itemKey in obj) {
                if (obj.hasOwnProperty(itemKey)) {
                    obj[itemKey] = wannaChangeValue(obj[itemKey]);
                }
            }
        } else {
            alert(obj);
            if (obj == someValue) {
                alert('got it! now change...')
                //change someValue to newValue
                obj = someValue;
            }
        }
        return obj
    }
    
    wannaChangeValue(obj)
    

    显然这会改变对象本身的值,所以如果你想要一个全新的对象,你将不得不做一些不同的事情。

    【讨论】:

      【解决方案5】:

      您可以对对象使用递归调用。

      演示

      var object = { a: 1, b: 2, c: { a: '1', b: 2, c: {a: 'hello', b: 'HowAreYou?'} } },
        someValue = 'hello',
        newValue = 'bye';
      
      function wannaChangeValue(obj) {
        var itemKey;
        if (obj instanceof Object) {
          for (itemKey in obj) {
            if (obj.hasOwnProperty(itemKey)) {
              if (!(obj[itemKey] instanceof Object) && obj[itemKey] == someValue) {
                //alert(someValue + ' got it! now change...')
                //change someValue to newValue
                obj[itemKey] = newValue;
                break;
              } else {
                wannaChangeValue(obj[itemKey]);
              }
            }
          }
        }
      }
      wannaChangeValue(object);
      console.log(object)
      .as-console-wrapper {max-height: 100% !important;top: 0;}

      【讨论】:

      • 伙计,你只需要像下面的代码一样更改你的代码,它就会为你工作。 这是一个注释行,将被标记为 Too健谈。答案应该有解释。
      【解决方案6】:

      这是使用object-scan的解决方案

      // const objectScan = require('object-scan');
      
      const obj = { a: 1, b: 2, c: { a: 1, b: 2, c: { a: 'hello', b: 'HowAreYou?' } } };
      
      const replace = (input, oldValue, newValue) => objectScan(['**'], {
        abort: true,
        rtn: 'bool',
        filterFn: ({ value, parent, property }) => {
          if (value === oldValue) {
            parent[property] = newValue;
            return true;
          }
          return false;
        }
      })(input);
      
      console.log(replace(obj, 'hello', 'bye')); // returns true iff replace happened
      // => true
      console.log(obj);
      // => { a: 1, b: 2, c: { a: 1, b: 2, c: { a: 'bye', b: 'HowAreYou?' } } }
      .as-console-wrapper {max-height: 100% !important; top: 0}
      <script src="https://bundle.run/object-scan@13.7.1"></script>

      免责声明:我是object-scan的作者

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-28
        • 1970-01-01
        • 2022-01-01
        • 1970-01-01
        • 2022-11-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多