patternjavascriptMinor
Javascript querystring to object conversion
Viewed 0 times
javascriptquerystringobjectconversion
Problem
The below code converts the window.location.search querystring into a JavaScript object. In particular, if a key occurs more than once the resulting value in the object will be an array. Please feel free to comment on both readability and speed of execution. Thanks!
window.location.search.split(/[?&]/g).reduce(function (prev, cur, idx, arr) {
var segment = cur.split("="),
key = segment[0],
val = segment[1];
if (prev[key]) {
if (prev[key] instanceof Array) {
prev[key].push(val);
} else {
prev[key] = [prev[key], val];
}
} else {
prev[key] = val;
}
return prev;
}, { });Solution
The line
Making an array out of repeating keys is fallacious - if a key is exactly repeated in a query string, only the right-most instance of that query string value will be received by the server. Further, in cases where the query string contains validly structured arrays (
EDIT
To clarify my remarks about duplicating keys, I purhaps mistakenly restricted my comments to Apache(Linux or Windows)/PHP - certainly other languages and platforms are relevant to the discussion. In the PHP language (what I am most familiar with), the query string
... as you can see, only the right-most value is the only one passed into the script. The way PHP expects duplicate query string keys is by use of
This behavior is the same for POST data on PHP - you must use
I am not set up to confirm the behavior of this in ASP (or other languages), however research has indicated that my assertion is still somewhat valid: https://stackoverflow.com/questions/6395290/how-may-i-add-integer-list-to-route/6396793#6396793. Please confirm if you are able: from what I have gathered the values would be passed to script as a comma-delimited list, but the language itself still rejects working with duplicate keys and a workaround is required.
If you can add some data about handling of duplicate keys in other server languages, please feel free to edit them into this answer. That said, I feel my criticism of this script's handling of duplicate keys stands, as well as the issue with "properly formed" (PHP) arrays in the query string -
if (typeof prev[key] === typeof []) { is... weird. If you're checking for a type specifically, check for it: if (typeof prev[key] === 'object') { - the way you're doing it there causes a new array literal to be instantiated needlessly, as well as a superfluous typeof operation, both inefficient and outright unnecessary.Making an array out of repeating keys is fallacious - if a key is exactly repeated in a query string, only the right-most instance of that query string value will be received by the server. Further, in cases where the query string contains validly structured arrays (
test=1&test2[]=2&test2[]=4), your code ends up with a key like test[], which is a nasty to access: results['test2[]'] is the only way to get at it (no dot syntax allowed).EDIT
To clarify my remarks about duplicating keys, I purhaps mistakenly restricted my comments to Apache(Linux or Windows)/PHP - certainly other languages and platforms are relevant to the discussion. In the PHP language (what I am most familiar with), the query string
test=1&test=2 will result in:var_export($_GET);
/* array (
'test' => '2',
) */... as you can see, only the right-most value is the only one passed into the script. The way PHP expects duplicate query string keys is by use of
[] in the query: test[]=1&test[]=2var_export($_GET);
/*array (
'test' =>
array (
0 => '1',
1 => '2',
),
)*/This behavior is the same for POST data on PHP - you must use
name="myField[]" if multiple fields will use the same name, otherwise, only the last item in the form with a given name will be populated in PHP's $_POST data.I am not set up to confirm the behavior of this in ASP (or other languages), however research has indicated that my assertion is still somewhat valid: https://stackoverflow.com/questions/6395290/how-may-i-add-integer-list-to-route/6396793#6396793. Please confirm if you are able: from what I have gathered the values would be passed to script as a comma-delimited list, but the language itself still rejects working with duplicate keys and a workaround is required.
If you can add some data about handling of duplicate keys in other server languages, please feel free to edit them into this answer. That said, I feel my criticism of this script's handling of duplicate keys stands, as well as the issue with "properly formed" (PHP) arrays in the query string -
result['test[]'] is nasty.Code Snippets
var_export($_GET);
/* array (
'test' => '2',
) */var_export($_GET);
/*array (
'test' =>
array (
0 => '1',
1 => '2',
),
)*/Context
StackExchange Code Review Q#6062, answer score: 2
Revisions (0)
No revisions yet.