Javascript:键/值存储在具有多层嵌套的对象中

时间:2020-04-24 06:41:16

标签: javascript javascript-objects

我得到了两个数组:-

var keys = ['a.b', 'a.c.d', 'a.e', 'h[0]'];
var values = [10, 20, {}, 40];

我想要的输出是:-

{
    a: { 
         b: 10, 
         c: {
            d: 20
         }, 
         e: {}
    },
    h: [40]
}

到目前为止我尝试过的是

let constructObject = (keys, values) => {
    let output = {};
    for(let i = 0; i<keys.length; i++) {
        let props = keys[i].split('.');
        for(let j=0; j<props.length;j++) {
            if(props.length > (j+ 1)) {
                if(output[props[j]] == undefined) {
                  output[props[j]] = {};
                }
            } else {
              output[props[j]] = values[i];
            }
        }
    }
    return output;
}

上面的代码没有嵌套得更深。我也尝试使用for循环来存储嵌套级别密钥,但无法获得任何存储密钥的方法,因为javascript仅允许存储值,而不是嵌套级别密钥。

1 个答案:

答案 0 :(得分:1)

您可以将路径分成较小的部分,例如属性和索引,并通过尊重下一个键来构建新对象,并确定是否必须采用数组或对象。

function setValue(target, keys, value) {
    const
        isWrapped = s => s.startsWith('[') && s.endsWith(']'),
        unwrap = s => isWrapped(s) ? s.slice(1, -1) : s,
        path = keys.match(/\[[^\]+]\]|[^\.\[\]]+/g),
        last = path.pop();

    path
        .reduce((o, k, i, { [i + 1]: next = last }) =>
            o[unwrap(k)] = o[unwrap(k)] || (isWrapped(next) ? [] : {}), target)
        [unwrap(last)] = value;
}

var keys = ['a.b', 'a.c.d', 'a.e', 'h[0]'],
    values = [10, 20, {}, 40],
    i,
    l = keys.length,
    result = {};

for (i = 0; i < l; i++) setValue(result, keys[i], values[i]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }