Unflatten JS对象和转换阵列

Unflatten JS对象和转换阵列

问题描述:

我已经使用扁平化的对象,像这样的功能:Unflatten JS对象和转换阵列

let object = { 
    a: 1, 
    b: [ 
    { c: 2 }, 
    { c: 3 } 
    ] 
}; 

flatten(object) 
// returns { 
    'a': 1, 
    'b.0.c': 2, 
    'b.1.c': 3 
} 

我需要unflatten对象,但也恢复阵列他们如何。我有以下代码:

unflatten(obj) { 
    let final = {}; 

    for (let prop in obj) { 
     this.assign(final, prop.split('.'), obj[prop]); 
    } 

    return final; 
    } 

    assign(final, path, value) { 
    let lastKeyIndex = path.length-1; 
    for (var i = 0; i < lastKeyIndex; ++ i) { 
     let key = path[i]; 
     if (!(key in final)) { 
     final[key] = {}; 
     } 
     final = final[key]; 
    } 
    final[path[lastKeyIndex]] = value; 
    } 

其中工程大部分,但它把像这样的数组:

{ 
    a: 1, 
    b: { // Notice how b's value is now an object 
    "0": { c: 2 }, // Notice how these now have a key corresponding to their index 
    "1": { c: 3 } 
    } 
} 

而我需要b是像阵列之前:

{ 
    a: 1, 
    b: [ 
    { c: 2 }, 
    { c: 3 } 
    ] 
} 

我不知道该从哪里出发。它需要能够处理阵列就像一个任意号码:

'a.b.0.c.0.d', 
'a.b.0.c.1.d', 
'a.b.1.c.0.d', 
'a.b.1.c.1.d', 
'a.b.1.c.2.d', 
// etc 

它需要香草JS,但ES2015是罚款。它假定任何一个数字键实际上都是数组的一部分。

如果有人有任何建议,很感谢!

当你发现keyfinal,你应该检查,看看是否在路径中的下一个关键是只有数字(使用正则表达式),如果是这样,分配到阵列的代替的对象:

if (!(key in final)) { 
    final[key] = /^\d+$/.test(path[i + 1]) ? [] : {}; 
} 

let object = { 
 
    a: 1, 
 
    b: [{ 
 
     c: 2 
 
    }, 
 
    { 
 
     c: 3 
 
    } 
 
    ] 
 
}; 
 

 
let flattened = { 
 
    'a': 1, 
 
    'b.0.c': 2, 
 
    'b.1.c': 3 
 
} 
 

 
function unflatten(obj) { 
 
    let final = {}; 
 

 
    for (let prop in obj) { 
 
    assign(final, prop.split('.'), obj[prop]); 
 
    } 
 

 
    return final; 
 
} 
 

 
function assign (final, path, value) { 
 
    let lastKeyIndex = path.length - 1; 
 
    for (var i = 0; i < lastKeyIndex; ++i) { 
 
    let key = path[i]; 
 
    if (!(key in final)) { 
 
     final[key] = /^\d+$/.test(path[i + 1]) ? [] : {}; 
 
    } 
 
    final = final[key]; 
 
    } 
 
    final[path[lastKeyIndex]] = value; 
 
} 
 

 
console.log(unflatten(flattened))
.as-console-wrapper { min-height: 100vh; }

您可以迭代键,然后拆分单个属性的字符串。为了构建一个新的对象,你可以检查数字并为这些属性创建一个数组。

function setValue(object, path, value) { 
 
    var way = path.split('.'), 
 
     last = way.pop(); 
 

 
    way.reduce(function (o, k, i, kk) { 
 
     return o[k] = o[k] || (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}); 
 
    }, object)[last] = value; 
 
} 
 

 
function unFlatten(object) { 
 
    var keys = Object.keys(object), 
 
     result = isFinite(keys[0][0]) ? [] : {}; 
 
    keys.forEach(function (k) { 
 
     setValue(result, k, object[k]); 
 
    }); 
 
    return result; 
 
} 
 

 
console.log(unFlatten({ 
 
    'a': 1, 
 
    'b.0.c': 2, 
 
    'b.1.c': 3 
 
})); 
 
console.log(unFlatten({ 
 
    '0': 1, 
 
    '1.0.c': 2, 
 
    '1.1.c': 3 
 
}));
.as-console-wrapper { max-height: 100% !important; top: 0; }