मैंने कुछ कोड को समतल और संयुक्त-समतल जटिल / नेस्टेड JSON ऑब्जेक्ट्स में फेंक दिया। यह काम करता है, लेकिन यह थोड़ा धीमा है ('लंबी स्क्रिप्ट' चेतावनी को ट्रिगर करता है)।
चपटे नामों के लिए मुझे चाहिए "।" परिसीमन और सरणियों के लिए [INDEX] के रूप में।
उदाहरण:
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}
मैंने एक बेंचमार्क बनाया कि ~ मेरे उपयोग के मामले का अनुकरण करता है http://jsfiddle.net/WSzec/
- एक नेस्टेड JSON ऑब्जेक्ट प्राप्त करें
- इसे समतल करें
- इसके माध्यम से देखें और चपटा होने पर संभवतः इसे संशोधित करें
- अनफ्लैट करें इसे वापस मूल नेस्टेड स्वरूप में भेज दिया जाना चाहिए
मैं तेज़ कोड पसंद करूँगा: स्पष्टीकरण के लिए, कोड जो JSFiddle बेंचमार्क ( http://jsfiddle.net/WSzec/ ) को पूर्ण करता है , IE 9+, FF 24+ और Chrome 29 में काफी तेज़ (~ 20% + अच्छा होगा) +।
यहां प्रासंगिक जावास्क्रिप्ट कोड है: करंट फास्टेस्ट: 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 ने @Bergi के कार्यान्वयन के लिए उपरोक्त संशोधन किया जो वर्तमान में सबसे तेज है। एक तरफ के रूप में, "regex.exec" के बजाय ".indexOf" का उपयोग करना FF में लगभग 20% तेज है लेकिन क्रोम में 20% धीमा है; तो मैं regex के साथ रहना आसान हूँ क्योंकि यह सरल है (यहाँ indexOf का उपयोग करने का मेरा प्रयास regex http://jsfiddle.net/WSzec/2/ ) को बदलने के लिए है ।
EDIT 2 बिल्डिंग @Bergi के विचार पर मैं एक तेज गैर-रेगेक्स संस्करण (FF में 3x और क्रोम में 10% तेज) बनाने में कामयाब रहा। http://jsfiddle.net/WSzec/6/ इसमें (वर्तमान में) प्रमुख नामों के नियमों को लागू करने के लिए बस, चाबियाँ एक पूर्णांक के साथ शुरू नहीं हो सकती हैं या एक अवधि शामिल कर सकते हैं।
उदाहरण:
- {"foo": {"bar": [0]}} => {"foo.bar.0": 0}
EDIT 3 @AaditMShah के इनलाइन पथ पार्सिंग दृष्टिकोण (String.split के बजाय) को जोड़ने से अनफ़्लैट प्रदर्शन को बेहतर बनाने में मदद मिली। समग्र प्रदर्शन में सुधार के साथ मैं बहुत खुश हूं।
नवीनतम jsfiddle और jsperf:
[1].[1].[0]
मुझे गलत लगता है। क्या आप सुनिश्चित हैं कि यह वांछित परिणाम है?