Object.entries(Array.from(new URLSearchParams("foo=1&foo=2&foo=3&blah=a&blah=b").entries()).reduce((a,[k,v]) => ({ ...a, [k]: [...a[k] ?? [], v] }), {})).map(([key, values]) => `${key}=${values.join(",")}`).join("&");
Object.entries(Array.from(new URLSearchParams("foo=1&foo=2&foo=3&blah=a&blah=b").entries()).reduce((a,[k,v]) => ({ ...a, [k]: [...a[k] ?? [], v] }), {})).map(([key, values]) => `${key}=${values.join(",")}`).join("&");
Note that this unfortunately common pattern is quadratic, which is usually not a good idea, and can have conflicts between entries and properties of Object.prototype. A similar implementation without those problems:
.reduce((a, [k, v]) => a.has(k) ? a.set(k, [v]) : (a.get(k).push(v), a), new Map())
And an alternate implementation: const input = new URLSearchParams("foo=1&foo=2&foo=3&blah=a&blah=b");
const result = new URLSearchParams();
for (const key of input.keys()) {
if (!result.has(key)) {
result.set(key, input.getAll(key).join(","));
}
}
return String(result);I enjoy reading people's off-the-cuff code golf stuff and usually learn something.
I was hoping other people to come up modern solutions to this same original problem.
Even my solution is questionable, because it relies on generating new URLSearchParams with strings, if one wants to be secure the reduce should take URLSearchParams as accumulator and add the items there.
Edit: Woah, made a hash of that before going in and fixing all the typos from my phone keyboard.