如何从键列表和值创建嵌套对象?

时间:2015-05-12 05:34:08

标签: javascript arrays object

我正在尝试提供一个脚本,该脚本将获取一组键和一个值并返回一个对象:

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值中已包含的任何数据都不会被删除。

1 个答案:

答案 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的最后一个元素。