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

yve*_*esb 2 javascript arrays object

我试图想出一个脚本,它将获取一组键和一个值并返回一个对象:

keys = ['a', 'b', 'c'];
value = 'hello';
Run Code Online (Sandbox Code Playgroud)

我试图得到这个:

{'a': {'b': {'c': 'hello'}}}
Run Code Online (Sandbox Code Playgroud)

我的代码:

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];
}
Run Code Online (Sandbox Code Playgroud)

另外,我想确保data每当使用不同的密钥时,任何已包含在值中的数据都不会被删除.

the*_*eye 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' } } }
Run Code Online (Sandbox Code Playgroud)

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' } } }
Run Code Online (Sandbox Code Playgroud)

即使这样也可以简洁地写成,就像这样

for (var i = 0; i < keys.length - 1; i++) {
    temp = (temp[keys[i]] = {});
}
temp[keys[keys.length - 1]] = value;
Run Code Online (Sandbox Code Playgroud)

我们迭代keys除最后一个之外的所有内容,并且每次都将新对象分配给当前键,因为我们将其分配回来temp,在下一次迭代时temp将引用新创建的对象.最后,我们将其分配value给最后一个元素keys.