Skip to content

Instantly share code, notes, and snippets.

@justsml
Last active October 2, 2016 22:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justsml/03b7c98aee775b33033e10f60cd5198d to your computer and use it in GitHub Desktop.
Save justsml/03b7c98aee775b33033e10f60cd5198d to your computer and use it in GitHub Desktop.
Key Value Parser & Stringify Example: QueryString- & Hash-Style String Parsing & Encoding Using `Functional Programming` in JavaScript!
/**
* Key Value Helpers
* Features QueryString & Hash Helper Utils
* API for `QS` & `Hash` inspired by the `JSON` browser API.
*
* Implements `parse` & `stringify`
*
* JSON.stringify({ foo: 'bar' })
* -> '{"foo":"bar"}'
* QS.stringify({ foo: 'bar' })
* -> 'foo=bar'
*
* The 4 following lines return (essentially) the same object:
* JSON.parse('{"foo":"bar","bar":"baz"}')
* QS.parse('?foo=bar&bar=baz')
* QS.parse('foo=bar&bar=baz')
* Hash.parse('#foo=bar&bar=baz')
* // ^^^ All Return:
* -> { foo: 'bar', bar: 'baz' }
*
* @author Dan Levy <dan@danlevy.net>
*/
// Functional Programming Example in JavaScript!!!
export const QS = {parse, stringify}; //<-- primary API export, (think JSON api)
export const Hash = {parse, stringify}; //<-- Also works for hash key=value strings
export function parse(s) {
const keyValify = kv => kv.split(/=/, 2); // < split limit=2 to stop data being truncated
const packObject = (obj = {}, [key, val]) => {
obj[dec(key)] = dec(val);
return obj;
}
return typeof s === 'string' && s
.replace(/^[\?#]?/, '') // trim any unwanted ?/# prefix
.split(/&/) // make array of keyval chunks
.map(keyValify) // split keyval str on "=" char (so, we have array of tuples)
//Finally, packObject uses some new ES2015/ES6 awesomeness:
// 1. Destructuring in params: [key, val]
// 2. Param defaults
// 3. Arrow functions (as named vars for overall readability)
.reduce(packObject);
}
export function stringify(obj) {
return typeof obj === 'object' && Object
.keys(obj)
.reduce((qs, key) => qs.concat(`${enc(key)}=${enc(obj[key])}`), [])
.join('&') || '';
}
/* Disclaimer: while this is NOT the fastest, IMHO it is the prettiest to humans in both code, flame graph & stacktrace forms. */
const enc = encodeURIComponent, // <-- aliases
dec = decodeURIComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment