Bunun eski bir konu olduğunu biliyorum, ama belki de bununla hala bir ilgisi var?
Jacky Li'nin iyi çözümünden esinlenerek, girdi olarak rastgele dizi ve nesne kombinasyonlarını da dikkate alabilmek amacıyla kendime ait küçük bir varyasyon denedim. PHP'nin bunu nasıl yapacağına baktım ve "benzer" bir şey elde etmeye çalıştım. İşte kodum:
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;
}
İşlev str-argument olmadan çağrılırsa window.location.search.slice(1), girdi olarak kabul edilir.
Bazı örnekler:
['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')
sonuçlanır
{"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
Jacky Li'nin çözümü ise adüz bir nesne olarak dış kabı üretecekti.
{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output
getargs() Bu düzeyin bir nesne mi (sayısal olmayan dizin) yoksa bir dizi mi (sayısal veya boş) olacağını belirlemek için herhangi bir düzey için ilk verilen dizine bakar, böylece yukarıda listelenen (no. 6) listedeki çıktıyla sonuçlanır.
Mevcut nesne bir diziyse null, boş konumları temsil etmek için gereken her yere eklenir. Diziler her zaman ardışık olarak numaralandırılır ve 0 tabanlıdır).
Not, örnekte hayır. 8 Boş indisler için "otomatik artırma", şimdi bir dizi değil, bir nesneyle uğraşıyor olsak da, hala çalışıyor.
Test ettiğim kadarıyla , kabul edilen cevapta bahsedilen getargs()Chriss Roger'ın harika jQuery $.deparam() eklentisiyle hemen hemen aynı şekilde davranıyor . Temel fark olduğunu getargsjQuery olmadan çalışır ve bu does ederken nesnelerde AUTOINCREMENT $.deparam()olacak değil bunu:
JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);
sonuçlanır
{"3":["7","99"],"x":"hi","undefined":"13"}
In $.deparam()endeksi []bir olarak yorumlanır undefinedyerine autoincremented sayısal endeksinin.
+. Şimdi hepsinin yerini alıyor!