There are at least 2×5 things you could mean by "parsing" a query string in Javascript

  • What data type do you want returned?
    • Map
    • Object
  • How do you want duplicate keys handled?
    • Just the first item
    • Just the last item
    • All the items, as a Set
    • All the items, as an Array
    • Throw an error

As a quick exercise, here is a sampler of all those (if you're in a hurry, just copy the first two or three functions):

function _parse_qs_array(search) {
	let m = search.match(/^\?(.+)$/s);
	let params = m ? m[1].split('&') : new Array();
	return params.map(s => {
		let [key, value] = s.match(/^(.*?)(?:=(.*))?$/s).slice(1);
		key = decodeURIComponent(key.replaceAll('+', '%20'));
		value = (value !== undefined ) ? decodeURIComponent(value.replaceAll('+', '%20')) : null;
		return [key, value];
	});
}


function parse_qs_map(search=window.location.search) {
	return new Map(_parse_qs_array(search));
}

function parse_qs_obj(search=window.location.search) {
	return Object.fromEntries(_parse_qs_array(search));
}


function parse_qs_map_first(search=window.location.search) {
	return new Map(_parse_qs_array(search).reverse());
}

function parse_qs_obj_first(search=window.location.search) {
	return Object.fromEntries(_parse_qs_array(search).reverse());
}


function parse_qs_map_all(search=window.location.search) {
	const map = new Map();
	_parse_qs_array(search).forEach(([key, value]) => {
		if(! map.has(key) ) map.set(key, new Set());
		map.get(key).add(value);
	});
	return map;
}

function parse_qs_obj_all(search=window.location.search) {
	const obj = new Object();
	_parse_qs_array(search).forEach(([key, value]) => {
		if( obj[key] === undefined ) obj[key] = new Set();
		obj[key].add(value);
	});
	return obj;
}


function parse_qs_map_all_ordered(search=window.location.search) {
	const map = new Map();
	_parse_qs_array(search).forEach(([key, value]) => {
		if(! map.has(key) ) map.set(key, new Array());
		map.get(key).push(value);
	});
	return map;
}

function parse_qs_obj_all_ordered(search=window.location.search) {
	const obj = new Object();
	_parse_qs_array(search).forEach(([key, value]) => {
		if( obj[key] === undefined ) obj[key] = new Array();
		obj[key].push(value);
	});
	return obj;
}


function parse_qs_map_1(search=window.location.search) {
	const map = new Map();
	_parse_qs_array(search).forEach(([key, value]) => {
		if( map.has(key) ) throw new SyntaxError('duplicate key');
		map.set(key, value);
	});
	return map;
}

function parse_qs_obj_1(search=window.location.search) {
	const obj = new Object();
	_parse_qs_array(search).forEach(([key, value]) => {
		if( obj[key] !== undefined ) throw new SyntaxError('duplicate key');
		obj[key] = value;
	});
	return obj;
}

Leave a Reply

Your email address will not be published.