简体   繁体   中英

Access nested object property and update its value through Generic method

I want create a generic method which will access a nested object property and update its value passed as argument.

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

This is my skeleton of the generic method

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

You could do this with reduce method, where you check if current value exists and if length of your string key is equal to current element and then change value.

 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) 

You're on the right track. I would go ahead and do it like this. THis way you can pass an array in of the value you want to change (ie ['marks', 'sub1'] ) and it will change whatever value you want. See the below example of how I change student.marks.sub1 and student.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')); 

[Immediate solution] I would suggest something like:

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;
}

[Explaining] Following you function signature, I reason by

  1. spliting the "path string" by '.' and therefore get an array in order to navigate through the object.
  2. Create a loop by using the keys and navigate/ validate the object till reach the wanted prop - if the path is valid to the object, everything goes ok otherwise the loop stops and the function returns false.

Something I assumed but not mentioned by you is the function returned value - true if everything goes well and false if not (no propPath or if the object is "incorrect").

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM