我正在尝试提供一个脚本,该脚本将获取一组键和一个值并返回一个对象:
keys = ['a', 'b', 'c'];
value = 'hello';
我正试图解决这个问题:
{'a': {'b': {'c': 'hello'}}}
我的代码:
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];
}
另外,我想确保只要使用不同的密钥,data
值中已包含的任何数据都不会被删除。
答案 0 :(得分:10)
您可以使用Array.prototype.reduceRight
,就像这样
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
将从右到左处理数组。每次我们创建一个新对象并将旧对象存储在当前密钥名称中。因此,当我们逐个迭代时,我们正在增加对象的嵌套。我们将value
作为最后一个参数传递,这将是第一次用作pastResult
。
如果您想修复原始代码,只需停止将新对象分配给data
并使用其他变量,例如
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' } } }
即便如此,也可以简洁地写出来,就像这样
for (var i = 0; i < keys.length - 1; i++) {
temp = (temp[keys[i]] = {});
}
temp[keys[keys.length - 1]] = value;
我们迭代除最后一个之外的所有keys
,并且每次都将新对象分配给当前密钥,因为我们将其分配回temp
,在下一次迭代temp
将引用新创建的对象。最后,我们将value
分配给keys
的最后一个元素。