2017-03-07 85 views
3

我已經使用扁平化的對象,像這樣的功能: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是罰款。它假定任何一個數字鍵實際上都是數組的一部分。

如果有人有任何建議,很感謝!

回答

1

當你發現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; }

0

您可以迭代鍵,然後拆分單個屬性的字符串。爲了構建一個新的對象,你可以檢查數字併爲這些屬性創建一個數組。

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; }