在javascript中遍历嵌套的json文件时替换值

Posted

技术标签:

【中文标题】在javascript中遍历嵌套的json文件时替换值【英文标题】:Replace value while iterating through nested json file in javascript 【发布时间】: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 对象的解决方案,而不知道更改这个值的路径。也许这是一个完全错误的方法...... 提前致谢!

【问题讨论】:

Find and update in nested json object 的可能重复项。另一个可能有帮助的链接:***.com/questions/15523514/… 【参考方案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的作者

【讨论】:

以上是关于在javascript中遍历嵌套的json文件时替换值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中的子项之间遍历以从 JSON 创建面包屑 UI

求jsp json数组遍历方法

在 Swift 5.1 中循环遍历多维/嵌套 JSON 数据

Django:如何遍历 html 中的嵌套 Json 对象

python无限遍历,实现在多维嵌套字典列表元组的JSON中获取数据

json数组存储了两个对象,要怎么遍历