Last active
October 2, 2016 22:59
-
-
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!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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