Parse bracket-notation query parameters
Once filters get nested, flat key-value parsing is not enough: APIs and form libraries encode structure into the key itself with bracket notation. Rebuilding the object from that is a neat exercise in walking a path and creating containers as you go.
Implement parseNestedQuery(search) returning a nested plain object. Strip one leading ?, split on &, and skip empty segments. Split each segment on its first =; a segment with no = has the value "".
Read the bracket structure from the **raw** key before decoding: the text before the first [ is the base key, and each following [...] is one more path segment. Then decode each segment and the value individually by replacing + with a space and calling decodeURIComponent, falling back to the raw text if that throws — so a percent-encoded bracket never changes the structure.
An empty segment [] means append to an array, so tags[]=a&tags[]=b gives { tags: ["a", "b"] }. Every other segment, **including a numeric one**, is an ordinary object key, so a[0]=x gives { a: { "0": "x" } }. Containers are created as you walk: a segment is an array when the next segment is [] and a plain object otherwise, and if a [] is followed by further segments a new object is appended for each pair. A repeated non-array key is overwritten, so the last value wins. An empty input returns {}.
Arguments
searchstring- A query string, with or without a leading
?. Empty segments are tolerated and an empty input returns{}.
Returns
object — A nested plain object reflecting the bracket structure in the keys. [] segments produce arrays; every other segment is an object key, even when numeric.
Examples
parseNestedQuery("user[name]=Ada&user[address][city]=London");
// => { user: { name: "Ada", address: { city: "London" } } }Each [segment] adds one level of nesting.
parseNestedQuery("tags[]=a&tags[]=b");
// => { tags: ["a", "b"] }The empty [] marker appends to an array.
parseNestedQuery("?filter[tags][]=x&filter[tags][]=y&filter[q]=hello+world");
// => { filter: { tags: ["x", "y"], q: "hello world" } }Nested arrays and + decoded as space, all in one go.
parseNestedQuery("a[0]=x");
// => { a: { "0": "x" } }Numeric segments are object keys, not array indices — they stay strings.
What it has to do
- Strip an optional leading
?, split on&, and skip empty segments. - Read the bracket path from the raw key, then decode each key segment and the value separately, handling
+as a space. - Append to an array for the empty
[]segment. - Treat every other segment, including numeric ones, as an ordinary object key.
- Create arrays and objects on demand while walking the path, and return
{}for empty input.
Notes
- Reading the bracket path from the _raw_ key is critical: once you decode first, a percent-encoded bracket like
%5Bbecomes[and you can no longer tell structure from content. - This matches the behaviour of PHP, Rails and the
qslibrary — the format Rails forms serialise into and that most REST APIs built on those stacks expect.
Stuck? The javascript course covers everything this challenge needs.
- 1.parses flat pairs
- 2.builds nested objects from bracket paths
- 3.appends to an array for the empty bracket marker
- 4.mixes nesting with arrays and decodes plus as a space
- 5.treats a numeric segment as an object key and returns {} for empty input
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.