Reputation: 95
I am trying to come up with a script that would take an array of keys and one value and return an object:
keys = ['a', 'b', 'c'];
value = 'hello';
And I am trying to get this:
{'a': {'b': {'c': 'hello'}}}
My code:
var data = {};
for (var i=0; i < keys.length; i++) {
var key = keys[i];
if (i < keys.length -1) {
if (data[key] === undefined) {
data[key] = {};
}
} else {
data[key] = value;
}
data = data[key];
}
Also I want to make sure that any data that would already be contained in the data
value would not get erase whenever it uses a different key.
Upvotes: 2
Views: 892
Reputation: 239453
You can use Array.prototype.reduceRight
, like this
var keys = ['a', 'b', 'c'];
var value = 'hello';
console.log(keys.reduceRight(function (pastResult, currentKey) {
var obj = {};
obj[currentKey] = pastResult;
return obj;
}, value));
// { a: { b: { c: 'hello' } } }
reduceRight
will process the array from the right to left. And everytime we create a new object and store the old object against the current key name. So, as we iterate one by one, we are increasing the nesting of objects. We pass value
as the last parameter, which will be used as the pastResult
the very first time.
If you want to fix your original code, you just have to stop assigning new objects to data
and use another variable, like this
var keys = ['a', 'b', 'c'],
value = 'hello',
data = {},
temp = data;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (i < keys.length - 1) {
if (temp[key] === undefined) {
temp[key] = {};
}
} else {
temp[key] = value;
}
temp = temp[key];
}
console.log(data)
// { a: { b: { c: 'hello' } } }
Even this can be written succinctly, like this
for (var i = 0; i < keys.length - 1; i++) {
temp = (temp[keys[i]] = {});
}
temp[keys[keys.length - 1]] = value;
We iterate all the keys
except the last one and assign a new object to the current key every time and since we assign it back to temp
, on the next iteration temp
will refer the newly created object. And finally, we assign the value
to the last element of keys
.
Upvotes: 11