J'ai jeté un peu de code, ensemble, à s'aplatir et de l'onu-aplatir complexe/imbriquée objets JSON. Cela fonctionne, mais il est un peu lent (déclenche la "longue script' avertissement).
Pour le aplatie noms que je veux "." comme séparateur et [INDEX] pour les tableaux.
Exemples:
un-flattened | flattened
---------------------------
{foo:{bar:false}} => {"foo.bar":false}
{a:[{b:["c","d"]}]} => {"a[0].b[0]":"c","a[0].b[1]":"d"}
[1,[2,[3,4],5],6] => {"[0]":1,"[1].[0]":2,"[1].[1].[0]":3,"[1].[1].[1]":4,"[1].[2]":5,"[2]":6}
J'ai créé un point de repère qui ~simule mon cas d'utilisation http://jsfiddle.net/WSzec/
- Obtenir un imbriquée objet JSON
- L'aplatir
- Regardez à travers et éventuellement de le modifier tout aplati
- Unflatten de retour à l'état initial imbriquée format à être expédié
Je voudrais plus rapide code: Pour clarifier, le code qui complète le JSFiddle de référence (http://jsfiddle.net/WSzec/) beaucoup plus rapide (~20%+ serait bien) dans IE 9+, FF 24+ et google Chrome 29+.
Voici pertinentes du code JavaScript: Courant plus Rapide: http://jsfiddle.net/WSzec/6/
JSON.unflatten = function(data) {
"use strict";
if (Object(data) !== data || Array.isArray(data))
return data;
var result = {}, cur, prop, idx, last, temp;
for(var p in data) {
cur = result, prop = "", last = 0;
do {
idx = p.indexOf(".", last);
temp = p.substring(last, idx !== -1 ? idx : undefined);
cur = cur[prop] || (cur[prop] = (!isNaN(parseInt(temp)) ? [] : {}));
prop = temp;
last = idx + 1;
} while(idx >= 0);
cur[prop] = data[p];
}
return result[""];
}
JSON.flatten = function(data) {
var result = {};
function recurse (cur, prop) {
if (Object(cur) !== cur) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for(var i=0, l=cur.length; i<l; i++)
recurse(cur[i], prop ? prop+"."+i : ""+i);
if (l == 0)
result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop+"."+p : p);
}
if (isEmpty)
result[prop] = {};
}
}
recurse(data, "");
return result;
}
EDIT 1 Modifié ci-dessus pour @Bergi mise en œuvre, qui est actuellement le plus rapide. En aparté, à l'aide ".indexOf" au lieu de "regex.exec" est environ 20% plus rapide dans les FF, mais 20% plus lent en Chrome; donc je vais rester avec les regex, car il est plus simple (voici ma tentative à l'aide indexOf pour remplacer les regex http://jsfiddle.net/WSzec/2/).
EDIT 2 Bâtiment sur @Bergi l'idée, j'ai réussi à créé un rapide non-regex version (3x plus rapide dans FF et ~10% plus rapide dans google Chrome). http://jsfiddle.net/WSzec/6/ Dans le présent (l'actuelle), la mise en œuvre des règles pour les noms de clés sont tout simplement, les clés ne peuvent pas commencer par un nombre entier ou contiennent une période.
Exemple:
- {"foo":{"bar":[0]}} => {"foo.bar.0":0}
EDIT 3 en Ajoutant @AaditMShah 'inline chemin de l'analyse de l'approche (plutôt que de la Chaîne.split) a contribué à améliorer la unflatten performance. Je suis très heureux avec l'ensemble de l'amélioration de la performance atteint.
La dernière jsfiddle et jsperf: