kkapsner
Super Moderator
Hi Leute,
ihr kennt doch alle die PHP-Syntax für GET und POST (key=value) und die Besonderheit mit den eckigen Klammern (arr[]=1&arr[]=2 => arr ist ein Array mit [1, 2] - aber auch Abgefahreneres: arr[hallo][][was]=2&arr[hallo][0][das]=3 => arr ist ein "Array" mit {hallo: [{was: 2, das:3}]}).
Hab' das Ganze mal so gut wie möglich in JS nachgebildet (es werden sogar, wo möglich, echte Arrays erzeugt) und bitte euch, es auf Herz und Nieren zu testen:
Für (konstruktive) Kritik, Verbesserungsvorschläge und v.A. beobachtete Bugs bin ich euch sehr dankbar.
EDIT: rekursive Objekte jetzt "erlaubt"... es kommt hald eine Fehlermeldung...
ihr kennt doch alle die PHP-Syntax für GET und POST (key=value) und die Besonderheit mit den eckigen Klammern (arr[]=1&arr[]=2 => arr ist ein Array mit [1, 2] - aber auch Abgefahreneres: arr[hallo][][was]=2&arr[hallo][0][das]=3 => arr ist ein "Array" mit {hallo: [{was: 2, das:3}]}).
Hab' das Ganze mal so gut wie möglich in JS nachgebildet (es werden sogar, wo möglich, echte Arrays erzeugt) und bitte euch, es auf Herz und Nieren zu testen:
Code:
var queryString = {
parse: function(str){
var ret = {};
var retInfo = {};
if (str.charAt(0) === "?") str = str.substr(1);
var param = str.split("&");
for (var i = 0; i < param.length; i++){
var par = param[i].split("=");
switch (par.length){
case 1:
par[1] = "";
break;
case 2:
break;
default:
par[1] = par.slice(1).join("=");
}
var parts = [];
var name = decodeURIComponent(par[0]).replace(/\][^\[].+/, "]").replace(/\[([^\]]*)\]/g, function(m, c){parts.push(c); return "";});
var value = decodeURIComponent(par[1]);
if (!name) continue;
var partsLength = parts.length;
if (!partsLength){
ret[name] = value;
}
else {
if (!is.object(ret[name])){
ret[name] = {};
retInfo[name] = {nextIndex: 0, subObjects: {}, onlyDiggits: true};
}
var obj = ret[name];
var objInfo = retInfo[name];
parts.forEach(function(name, i){
if (!name){
name = objInfo.nextIndex;
objInfo.nextIndex++;
}
var diggitName = /^\d+$/.test(name);
if (!diggitName) objInfo.onlyDiggits = false;
if (i == partsLength - 1) obj[name] = value;
else {
if (!is.object(obj[name])){
obj[name] = {};
objInfo.subObjects[name] = {nextIndex: 0, subObjects: {}, onlyDiggits: true};
}
if (diggitName){
if (name > objInfo.nextIndex){
objInfo.nextIndex = parseInt(name, 10) + 1;
}
}
obj = obj[name];
objInfo = objInfo.subObjects[name];
}
});
}
}
function toArrayIfPossible(obj, objInfo){
if (!is.object(obj)) return obj;
var ret = objInfo.onlyDiggits? []: obj;
for (var i in obj){
if (obj.hasOwnProperty(i)){
ret[i] = toArrayIfPossible(obj[i], objInfo.subObjects[i]);
}
}
return ret;
}
return toArrayIfPossible(ret, {onlyDiggits: false, subObjects: retInfo});
},
stringify: function stringify(value){
var stringifyStack = [];
function process(value, namescope){
// recursion detection
if (stringifyStack.indexOf(value) > -1) throw new TypeError("recursive structure");
stringifyStack.push(value);
namescope = (namescope || "");
var ret = [];
if (namescope && is.array(value)){
var name = namescope + "[";
value.forEach(function(value, i){
ret.push(process(value, name + i + "]"));
});
}
else if (is.object(value)){
for (var name in value){
if (value.hasOwnProperty(name)){
var v = value[name];
if (namescope) name = namescope + "[" + name + "]";
ret.push(process(v, name));
}
}
}
else {
stringifyStack.pop();
return encodeURIComponent(namescope) + "=" + encodeURIComponent(value)
}
stringifyStack.pop();
return ret.join("&");
}
return process(value);
}
};
EDIT: rekursive Objekte jetzt "erlaubt"... es kommt hald eine Fehlermeldung...
Zuletzt bearbeitet: