如果有一个键名数组,则更改对象的深层嵌套键值

时间:2017-04-05 09:14:12

标签: javascript arrays object

我有一个对象和一组相同的对象键:

var obj = {
 'fieldOne': {
    'fieldTwo': {
        'fieldThree': {
            'fieldFour': {
                'someNestedKey': 'test'
            }
        }
    }
 }
}
var keysArr = ['fieldOne', 'fieldTwo', 'fieldThree', 'fieldFour', 'someNestedKey'];

有没有办法使用keys数组更改'someNestedKey'值?

只需通过索引访问'someNestedKey'就行不通,因为keys数组中可能包含更多或更少的键。 我尝试使用数组长度,但我似乎无法让它工作。 我对编程比较陌生,非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

您可以获取路径并检查是否存在以下元素。如果没有将对象分配给新属性。

然后返回属性的值。

最后指定值。

function setValue(object, path, value) {
    var way = path.slice(),
        last = way.pop();

    way.reduce(function (r, a) {
        return r[a] = r[a] || {};
    }, object)[last] = value;
}

var obj = { fieldOne: { fieldTwo: { fieldThree: { fieldFour: { someNestedKey: 'test' } } } } },
    keysArr = ['fieldOne', 'fieldTwo', 'fieldThree', 'fieldFour', 'someNestedKey'];

setValue(obj, keysArr, 42);
console.log(obj);

答案 1 :(得分:1)

是的,你可以!

var obj = {
 'fieldOne': {
    'fieldTwo': {
    'fieldThree': {
        'fieldFour': {
            'someNestedKey': 'test'
        }
    }
    }
 }
}

var keysArr = ['fieldOne', 'fieldTwo', 'fieldThree', 'fieldFour', 'value'];

var obj1 = obj;
for (var i = 0; i < keysArr.length - 1; i++) {
    if (obj1[keysArr[i]]) {
        obj1 = obj1[keysArr[i]];
    } else {
        break;
    }
}

obj1[Object.keys(obj1)[0]] = keysArr[keysArr.length - 1];

执行此代码后,'someNestedKey'将设置为'value'。

答案 2 :(得分:1)

试试这个。

var obj = {
 'fieldOne': {
    'fieldTwo': {
        'fieldThree': {
            'fieldFour': {
                'someNestedKey': 'test'
            }
        }
    }
 }
}
var keysArr = ['fieldOne', 'fieldTwo', 'fieldThree', 'fieldFour', 'someNestedKey'];

var setThis = function(obj, keysArr, valueToSet){

var ref=obj ;
keysArr.forEach(function(key, index){
                    if(index==keysArr.length-1)
                      ref[key] = valueToSet ;
                    else
    	                ref = ref[key] ;
              });
  alert(JSON.stringify(obj));
};  

setThis(obj, keysArr, "test123");

答案 3 :(得分:1)

您也可以尝试使用eval,但在使用前请参考When is JavaScript's eval() not evil?

逻辑:

  • 如果在路径初始化的位置正确构造了对象,则可以创建一个直接设置值的字符串。这样你就可以跳过循环。
  • 作为后备,如果存在未初始化内部任何值的情况,则可以循环路径并手动设置。

&#13;
&#13;
function updateValue(obj, path, value) {
  try {
    eval("obj[\"" + path.join("\"][\"") + "\"]=" + value)
    console.log("Used Eval")
  } catch (err) {
    path.reduce(function(p, c, i, a) {
      p[c] = (i === a.length - 1) ? value : p[c] || {};
      return p[c];
    }, obj);

    console.log("Used Loop")
  }
}

var obj = {
  'fieldOne': {
    'fieldTwo': {
      'fieldThree': {
        'fieldFour': {
          'someNestedKey': 'test'
        }
      }
    }
  }
}
var keysArr = ['fieldOne', 'fieldTwo', 'fieldThree', 'fieldFour', 'someNestedKey']
var keysArr1 = ['fieldOne', 'fieldTwo', 'fieldThree', 'fieldFive', 'someNestedKey']

updateValue(obj, keysArr, 10);
console.log(obj)

updateValue(obj, keysArr1, 10);
console.log(obj)
&#13;
&#13;
&#13;