मुझे पता है कि यह एक पुराना धागा है, लेकिन शायद अभी भी इसमें कुछ प्रासंगिकता है?
जैकी ली के अच्छे समाधान से प्रेरित होकर मैंने अपने स्वयं के थोड़े से बदलाव को इस उद्देश्य के साथ आज़माया कि इनपुट के रूप में सरणियों और वस्तुओं के मनमाने संयोजन का ध्यान रखने में सक्षम हो। मैंने देखा कि कैसे PHP ने इसे किया होगा और कुछ "समान" होने की कोशिश की। यहाँ मेरा कोड है:
function getargs(str){
var ret={};
function build(urlnam,urlval,obj){ // extend the return object ...
var i,k,o=obj, x, rx=/\[([^\]]*)\]/g, idx=[urlnam.replace(rx,'')];
while (x=rx.exec(urlnam)) idx.push(x[1]);
while(true){
k=idx.shift();
if(k.trim()=='') {// key is empty: autoincremented index
if (o.constructor.name=='Array') k=o.length; // for Array
else if (o===obj ) {k=null} // for first level property name
else {k=-1; // for Object
for(i in o) if (+i>k) k=+i;
k++;
}
}
if(idx.length) {
// set up an array if the next key (idx[0]) appears to be
// numeric or empty, otherwise set up an object:
if (o[k]==null || typeof o[k]!='object') o[k]=isNaN(idx[0])?{}:[];
o=o[k]; // move on to the next level
}
else { // OK, time to store the urlval in its chosen place ...
// console.log('key',k,'val',urlval);
o[k]=urlval===""?null:urlval; break; // ... and leave the while loop.
}
}
return obj;
}
// ncnvt: is a flag that governs the conversion of
// numeric strings into numbers
var ncnvt=true,i,k,p,v,argarr=[],
ar=(str||window.location.search.substring(1)).split("&"),
l=ar.length;
for (i=0;i<l;i++) {if (ar[i]==="") continue;
p=ar[i].split("=");k=decodeURIComponent(p[0]);
v=p[1];v=(v!=null)?decodeURIComponent(v.replace(/\+/g,'%20')):'';
if (ncnvt && v.trim()>"" && !isNaN(v)) v-=0;
argarr.push([k,v]); // array: key-value-pairs of all arguments
}
for (i=0,l=argarr.length;i<l;i++) build(argarr[i][0],argarr[i][1],ret);
return ret;
}
यदि फ़ंक्शन को str-argument के बिना कॉल किया जाता है तो यह window.location.search.slice(1)इनपुट के रूप में ग्रहण करेगा ।
कुछ उदाहरण:
['a=1&a=2', // 1
'x[y][0][z][]=1', // 2
'hello=[%22world%22]&world=hello', // 3
'a=1&a=2&&b&c=3&d=&=e&', // 4
'fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc', // 5
$.param({a:[[1,2],[3,4],{aa:'one',bb:'two'},[5,6]]}), // 6
'a[]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13',// 7
'a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13'// 8
].map(function(v){return JSON.stringify(getargs(v));}).join('\n')
का परिणाम
{"a":2} // 1
{"x":{"y":[{"z":[1]}]}} // 2
{"hello":"[\"world\"]","world":"hello"} // 3
{"a":2,"b":null,"c":3,"d":null,"null":"e"} // 4 = { a: 2, b: null, c: 3, d: null, null: "e" }
{"fld":[null,null,[2],[3,4],"bb","cc"]} // 5
{"a":[[1,2],[3,4],{"aa":"one","bb":"two"},[5,6]]} // 6
{"a":["hi",2,null,[7,99],13]} // 7
{"a":{"0":2,"3":[7,99],"4":13,"x":"hi"}} // 8
जबकि जैकी ली का समाधान aएक सादे वस्तु के रूप में बाहरी कंटेनर का उत्पादन करेगा
{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output
getargs() यह निर्धारित करने के लिए किसी भी स्तर के लिए पहले दिए गए सूचकांक को देखता है कि क्या यह स्तर एक ऑब्जेक्ट (गैर-संख्यात्मक सूचकांक) या एक सरणी (न्यूमेरिक या खाली) होगा, इस प्रकार आउटपुट के रूप में लिस्टिंग बोव (6 नंबर) में दिखाया गया है।
यदि वर्तमान वस्तु एक सरणी है तो nullखाली पदों का प्रतिनिधित्व करने के लिए जहां भी आवश्यक हो सम्मिलित करें। Arrays हमेशा लगातार क्रमांकित और 0-आधारित हैं)।
ध्यान दें, कि उदाहरण में नहीं। 8 खाली सूचकांकों के लिए "ऑटोइन्क्रिमेंट" अभी भी काम करता है, भले ही हम अभी एक वस्तु के साथ काम कर रहे हैं और एक सरणी नहीं।
जहां तक मैंने इसका परीक्षण किया है, मेरा स्वीकार किए गए उत्तर में उल्लिखित getargs()क्रिस रोजर के महान jQuery $.deparam() प्लगइन के लिए बहुत अधिक पहचान का व्यवहार करता है । मुख्य अंतर यह है कि getargsjQuery के बिना चलता है और यह वस्तुओं में स्वत: संचय करता है जबकि $.deparam()ऐसा नहीं करेगा :
JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);
का परिणाम
{"3":["7","99"],"x":"hi","undefined":"13"}
में $.deparam()सूचकांक []एक के रूप में व्याख्या की है undefinedएक autoincremented संख्यात्मक सूचकांक के बजाय।
+। अब यह उन सभी को बदल देता है!