2017-03-07 9 views
3

私はそうのようなオブジェクトを平坦化するために使用する機能を持って変換します。非平坦化JSオブジェクトと配列

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

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

を私はオブジェクトを非平坦化する必要がありますが、また、彼らはあったかに配列を元に戻します。私は、次のコードを持っている:ほとんどの部分は動作しますが、それはそうのような配列を扱う

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

:私はのような配列であることをbを必要とするのに対し

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

前:

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

関連する問題