简体   繁体   中英

set a property's value with unknown depth within an object in javascript

var params = {
    search: {
        make: "",
        model: ""
    }
}

function setVariable() {
    var value = "BMW";
    var key = "search.make";
    var arr = key.split(".");    //eg. ["search", "make"]
    params[arr[0]][arr[1]] = value;   // this works, but how do you
                                      // do it with unknown arr[] length?
}

How do I do this with an unknown arr[] length?

I have surmised that I probably need to do a recursive call, maybe passing something like arr.slice(1) within the function, but I have not been able to figure out what that should look like.

The following code traverses your params object until the given key is found. It assumes that key.split(".") returns a proper array of keys (so you might need to sanitize your inputs here further.

var params = {
    search: {
        make: "",
        model: ""
    }
}

function setVariable() {
    var value = "BMW";
    var key = "search.make";
    var arr = key.split(".");    //eg. ["search", "make"]

    var runner = params;
    for( var i=0, max=arr.length-1; i<max; ++i ) {
       // make sure the key exists
       runner[ arr[i] ] = runner[ arr[i] ] || {};
       // move one level deeper
       runner = runner[ arr[i] ];
    }

    // set the value in the last level
    runner[ arr[arr.length-1] ] = value;   
}

EDIT: wrt to the comment of Felix Kling: It assumes that you want previously not existant keys to be generated. Else you would have to put aa further check into the for loop and leave the function, if the key does not exist, instead of creating it.

var params = {
    search: {
        make: "",
        model: "",
        whatever: {
            foo: {
                bar: {
                    moo: 123,
                    meow: 'xyz'
                }
            }
        }
    }
};

function updatePath(obj, path, value) {
    var parts = path.split('.');
    var i, tmp;
    for(i = 0; i < parts.length; i++) {
        tmp = obj[parts[i]];
        if(value !== undefined && i == parts.length - 1) {
            tmp = obj[parts[i]] = value;
        }
        else if(tmp === undefined) {
            tmp = obj[parts[i]] = {};
        }
        obj = tmp;
    }
    return obj;
}

Demo:

> updatePath(params, 'search.whatever.foo.bar')
{ moo: 123, meow: 'xyz' }
> updatePath(params, 'search.whatever.foo.bar.moo')
123
> updatePath(params, 'search.whatever.foo.bar.moo', 'test')
'test'
> updatePath(params, 'search.whatever.foo.bar.moo')
'test'
> updatePath(params, 'search.whatever.foo.bar')
{ moo: 'test', meow: 'xyz' }
> updatePath(params, 'search.whatever.foo.bar.x.y.z', 'hi')
'hi'
> updatePath(params, 'search.whatever.foo.bar.x')
{ y: { z: 'hi' } }
> updatePath(params, 'search.whatever.foo.bar')
{ moo: 'test',
  meow: 'xyz',
  x: { y: { z: 'hi' } } }
>

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