0

I want to make/replace object from string in javascript.

var api_response = { key: "settings.options.height", val: 500 };
keys = api_response.key.split('.');

var settings = { options: { height: 0 } };

i have no idea how to replace value of settings.options.height to api.val. i tried to combine array to settings[keys[0]][keys[1]][keys[2]] = api.val

but what if i will have more or less keys than 3? Is here an function to map it?

2

4 Answers 4

0

One-liner

api_response.key.split('.').reduceRight((obj, key) => ({ [key]: obj }), api_response.val)

Ungolfed

api_response
  .key // access key prop
  .split('.') // split on dot
  .reduceRight((obj, key) => {
     return {
       [key]: obj // dynamic key generation
     };
  }, api_response.val);

The reduceRight is just what it sounds like: it reduces the array but starts at the right end instead of the left, and we feed it the .val as the seed for the innermost key/value pair.

Sign up to request clarification or add additional context in comments.

1 Comment

Its weird to me that this is the accepted answer - it is definitely clever, but it just builds an object with nested properties according to the path and the value, it does not modify an existing object - which is pretty clear to me what the OP is about. If the OP has a settings object with some interesting data where they want just one field to be overridden with the contents of the api_response descriptor - this will not work for them.
0

You'll have to write your own function. It's pretty much a for loop.

var api_response = { key: "settings.options.height", val: 500 };
var keys = api_response.key.split('.');
var obj = {}
var ptr = obj;
var last = obj;
for (var i = 0; i < keys.length; i++) {
  var key = keys[i]
  ptr[key] = ptr[key] || {}
  last = ptr;
  ptr = ptr[key]
}
if (keys.length) {
  last[keys[keys.length - 1]] = api_response.val;
}

console.log(obj)

Comments

0

If you are using node, you can install a library that takes care of it for you. I can also do the inverse action.

https://github.com/rhalff/dot-object

Comments

0

It looks like you want to have programmatic access to a deep data structure, where the path is determined by parsing a text query with a specific syntax - in your case, . as a path delimiter. It shouldn't be hard to implement a recursive function to drill down into the data structure using the path, but the main issue - from your example - is that the first item on the path describes a variable - and you can't programmatically search for a variable in the current context: you can only look for keys in objects. For example, if the settings variable is a window property, then you can start your search from the window object.

So basically you want to create a method that takes the root object (for example, window, as discussed above), look at the first element of the path and see if there's a property in that object with that name, and if so - call itself again with the result and the rest of the path.

A naive implementation might look like so:


function searchPath(object, path) {
    let [prefix, rest] = path.split(".",2);
    if (object[prefix] !== undefined) {
        if (rest.length > 0)
            return searchPath(object[prefix], rest);
        return object[prefix];
    }
    return undefined;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.