Skip to content

Instantly share code, notes, and snippets.

@brito
Last active March 10, 2017 01:17
Show Gist options
  • Save brito/3868026ce92b17cff7c2dc98e325fbd4 to your computer and use it in GitHub Desktop.
Save brito/3868026ce92b17cff7c2dc98e325fbd4 to your computer and use it in GitHub Desktop.
Automagical pivot table for unwieldy sheets
/*
Automagical Pivot "Table"
1. Export your unwieldy xls into csv
2. Paste csv into ES6 as example below
3. Inspect the JS object returned
*/
Example:
csv(`Name,ID,Category,USD
Alpha,123,Sales,"123,456"
Romeo,456,Sales,"123,456,789"`)
// NOTE
// 1. Backticks allow you to paste with quotes and newlines right away
// "Includes" (2 hoisted dependencies)
/*
┌─┐┌─┐┬ ┬
│ └─┐└┐┌┘
└─┘└─┘ └┘ w10 */
function csv(string){
let [labels, ...data] =
string
// 2. Only the "123,456,789" special case is handled
.replace(/"[\d,]+"/g, n => n.replace(/[",]/g,''))
.split('\n')
// 3. YMMV; using naive CSV parsing for simplicity
.map(text => text.split(','));
return Catalog(...data.map(row => zip(labels, row)));
function zip(labels, row){
return labels.reduce((data, key, i) =>
Object.assign(data, {[key]: row[i]})
, {});
}
}
/*
┌─┐┌─┐┌┬┐┌─┐┬ ┌─┐┌─┐
│ ├─┤ │ ├─┤│ │ ││ ┬
└─┘┴ ┴ ┴ ┴ ┴┴─┘└─┘└─┘ w10 */
function Catalog(...items){
return items.reduce((catalog), {});
function catalog(dict, item){
for (let [key, value] of Object.entries(item)){
let initial = key in dict? dict[key]: new Map;
switch (value.constructor.name){
case 'Array':
dict[key] = value.reduce(catalog, initial);
break;
case 'Object':
dict[key] = [value].reduce(catalog, initial);
break;
default:
dict[key] = archive(initial, value, item);
break;
}
}
return dict;
function archive(context, key, item){
context[key] = key in context ?
context[key].concat(item)
: [item];
return context;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment