访问嵌套对象 属性 并通过通用方法更新其值

Access nested object property and update its value through Generic method

我想创建一个通用方法来访问嵌套对象 属性 并更新作为参数传递的值。

This is my data structure
 var student = {
  name: 'Tom',
  address: {
    pincode: 43301,
    street: '12th Main',
    city: 'Some city',
  },
  marks: {
    sub1: 111,
    sub2: 222
  }
}

这是我的泛型方法框架

updatProperty(student, 'marks.sub1', 125) {
  // this method should return student object with marks.sub1 to be 125
}

I have refereed this link , but this will only return me a value

你走在正确的轨道上。我会继续这样做。通过这种方式,您可以传递一个包含您想要更改的值的数组(即 ['marks', 'sub1']),它会更改您想要的任何值。请参阅下面的示例,了解我如何更改 student.marks.sub1student.address.city:

var student = {
  name: 'Tom',
  address: {
    pincode: 43301,
    street: '12th Main',
    city: 'Some city',
  },
  marks: {
    sub1: 111,
    sub2: 222
  }
}

function updateProperty(student, keys, value) {
    obj = student;

    for(var i=0; i<keys.length-1; i++){
        obj = obj[keys[i]];
    }

    obj[keys[i]] = value;
    
    return student;
}


console.log(updateProperty(student, ['marks', 'sub1'], 125));
console.log(updateProperty(student, ['address', 'city'], 'New York'));

[立即解决] 我建议像这样:

function updatProperty(obj, propPath, value) {

    if(!propPath) return false;

    const keys = propPath.split('.');
    let pointer = obj,
        validPath = true;
    for (let i = 0; i < keys.length && validPath; i++) {

        let key = keys[i];

        if(i === (keys.length - 1)) pointer[key] = value;
        else {
            if(!pointer[key]) validPath = false;
            else pointer = pointer[key];
        }
    }

    return validPath;
}

[解释] 按照你的函数签名,我的理由是

  1. 用'.'拆分"path string"因此得到一个数组 为了在对象中导航。
  2. 使用 keys 并导航/验证对象直到到达想要的道具 - 如果路径对对象有效,则一切正常,否则循环停止并且函数 returns false.

我假设但你没有提到的是函数返回值 - 如果一切顺利则为 true,否则为 false(没有 propPath 或者如果对象是 "incorrect")。

希望对您有所帮助。

您可以使用 reduce 方法执行此操作,在该方法中检查当前值是否存在以及字符串键的长度是否等于当前元素,然后更改值。

var student = {"name":"Tom","address":{"pincode":43301,"street":"12th Main","city":"Some city"},"marks":{"sub1":111,"sub2":222}}

function updatProperty(obj, key, value) {
  key.split('.').reduce((r, e, i, a) => {
    if (r[e] && a.length - 1 == i) r[e] = value
    return r[e] || {}
  }, obj)
}

updatProperty(student, 'marks.sub1', 125);
console.log(student)