Converti object notazione punto javascript in object nidificato

Sto cercando di creare una funzione che possa espandere un object come:

{ 'ab.cd.e' : 'foo', 'ab.cd.f' : 'bar', 'ab.g' : 'foo2' } 

In un object nidificato:

 {ab: {cd: {e:'foo', f:'bar'}, g:'foo2'}} 

Come questa funzione php: Set :: expand ()

Senza usare eval, naturalmente.

Credo che questo sia ciò che stai cercando:

 function deepen(o) { var oo = {}, t, parts, part; for (var k in o) { t = oo; parts = k.split('.'); var key = parts.pop(); while (parts.length) { part = parts.shift(); t = t[part] = t[part] || {}; } t[key] = o[k] } return oo; } 

Per esempio:

 > JSON.stringify(deepen({'ab.cd.e' : 'foo', 'ab.cd.f' : 'bar', 'ab.g' : 'foo2'}))` "{"ab":{"cd":{"e":"foo","f":"bar"},"g":"foo2"}}" 

Se stai utilizzando Node.js (ad esempio, se non si taglia e incolla dal nostro modulo), prova questo pacchetto: https://www.npmjs.org/package/dataobject-parser

Costruito un modulo che esegue le operazioni avanti / indietro:

https://github.com/Gigzolo/dataobject-parser

È progettato come object autogestito in questo momento. Utilizzato istanziando un’istanza di DataObjectParser.

 var structured = DataObjectParser.transpose({ 'ab.cd.e' : 'foo', 'ab.cd.f' : 'bar', 'ab.g' : 'foo2' }); 

structured.data() restituisce il tuo object nidificato:

{ab: {cd: {e:'foo', f:'bar'}, g:'foo2'}}

Quindi ecco un esempio funzionante in JSFiddle:

http://jsfiddle.net/H8Cqx/

Il nome della funzione è terribile e il codice è stato rapidamente creato, ma dovrebbe funzionare. Si noti che questo modifica l’object originale, non sono sicuro se volessi creare un nuovo object che è la versione espansa di quello vecchio.

 (function(){ function parseDotNotation( str, val, obj ){ var currentObj = obj, keys = str.split("."), i, l = keys.length - 1, key; for( i = 0; i < l; ++i ) { key = keys[i]; currentObj[key] = currentObj[key] || {}; currentObj = currentObj[key]; } currentObj[keys[i]] = val; delete obj[str]; } Object.expand = function( obj ) { for( var key in obj ) { parseDotNotation( key, obj[key], obj ); } return obj; }; })(); var expanded = Object.expand({ 'ab.cd.e' : 'foo', 'ab.cd.f' : 'bar', 'ab.g' : 'foo2' }); JSON.stringify( expanded ); //"{"ab":{"cd":{"e":"foo","f":"bar"},"g":"foo2"}}" 

Derivato dalla risposta di Esailija , con correzioni per supportare più chiavi di primo livello.

 (function () { function parseDotNotation(str, val, obj) { var currentObj = obj, keys = str.split("."), i, l = Math.max(1, keys.length - 1), key; for (i = 0; i < l; ++i) { key = keys[i]; currentObj[key] = currentObj[key] || {}; currentObj = currentObj[key]; } currentObj[keys[i]] = val; delete obj[str]; } Object.expand = function (obj) { for (var key in obj) { if (key.indexOf(".") !== -1) { parseDotNotation(key, obj[key], obj); } } return obj; }; })(); var obj = { "pizza": "that", "this.other": "that", "alphabets": [1, 2, 3, 4], "this.thing.that": "this" } 

Uscite:

 { "pizza": "that", "alphabets": [ 1, 2, 3, 4 ], "this": { "other": "that", "thing": { "that": "this" } } } 

Violino

Devi convertire ogni chiave stringa in object. Usando la seguente funzione puoi ottenere il risultato del desiderio.

  function convertIntoJSON(obj) { var o = {}, j, d; for (var m in obj) { d = m.split("."); var startOfObj = o; for (j = 0; j < d.length ; j += 1) { if (j == d.length - 1) { startOfObj[d[j]] = obj[m]; } else { startOfObj[d[j]] = startOfObj[d[j]] || {}; startOfObj = startOfObj[d[j]]; } } } return o; } 

Ora chiama questa funzione

  var aa = { 'ab.cd.e': 'foo', 'ab.cd.f': 'bar', 'ab.g': 'foo2' }; var desiredObj = convertIntoJSON(aa); 

Qualcosa che funzioni, ma probabilmente non è il modo più efficace per farlo (si basa anche sul metodo Object.keys () di ECMA 5, ma può essere facilmente sostituito.

 var input = { 'ab.cd.e': 'foo', 'ab.cd.f': 'bar', 'ab.g': 'foo2' }; function createObjects(parent, chainArray, value) { if (chainArray.length == 1) { parent[chainArray[0]] = value; return parent; } else { parent[chainArray[0]] = parent[chainArray[0]] || {}; return createObjects(parent[chainArray[0]], chainArray.slice(1, chainArray.length), value); } } var keys = Object.keys(input); var result = {}; for(var i = 0, l = keys.length; i < l; i++) { createObjects(result, keys[i].split('.'), input[keys[i]]); } 

JSFiddle è qui .