UNPKG

@tidyjs/tidy

Version:

Tidy up your data with JavaScript, inspired by dplyr and the tidyverse

89 lines (86 loc) 2.87 kB
import { groupBy } from './groupBy.js'; import { tidy } from './tidy.js'; function pivotWider(options) { const _pivotWider = (items) => { const { namesFrom, valuesFrom, valuesFill, valuesFillMap, namesSep = "_" } = options; const namesFromKeys = Array.isArray(namesFrom) ? namesFrom : [namesFrom]; const valuesFromKeys = Array.isArray(valuesFrom) ? valuesFrom : [valuesFrom]; const wider = []; if (!items.length) return wider; const idColumns = Object.keys(items[0]).filter((key) => !namesFromKeys.includes(key) && !valuesFromKeys.includes(key)); const nameValuesMap = {}; for (const item of items) { for (const nameKey of namesFromKeys) { if (nameValuesMap[nameKey] == null) { nameValuesMap[nameKey] = {}; } nameValuesMap[nameKey][item[nameKey]] = true; } } const nameValuesLists = []; for (const nameKey in nameValuesMap) { nameValuesLists.push(Object.keys(nameValuesMap[nameKey])); } const baseWideObj = {}; const combos = makeCombinations(namesSep, nameValuesLists); for (const nameKey of combos) { if (valuesFromKeys.length === 1) { baseWideObj[nameKey] = valuesFillMap != null ? valuesFillMap[valuesFromKeys[0]] : valuesFill; continue; } for (const valueKey of valuesFromKeys) { baseWideObj[`${valueKey}${namesSep}${nameKey}`] = valuesFillMap != null ? valuesFillMap[valueKey] : valuesFill; } } function widenItems(items2) { if (!items2.length) return []; const wide = {...baseWideObj}; for (const idKey of idColumns) { wide[idKey] = items2[0][idKey]; } for (const item of items2) { const nameKey = namesFromKeys.map((key) => item[key]).join(namesSep); if (valuesFromKeys.length === 1) { wide[nameKey] = item[valuesFromKeys[0]]; continue; } for (const valueKey of valuesFromKeys) { wide[`${valueKey}${namesSep}${nameKey}`] = item[valueKey]; } } return [wide]; } if (!idColumns.length) { return widenItems(items); } const finish = tidy(items, groupBy(idColumns, [widenItems])); return finish; }; return _pivotWider; } function makeCombinations(separator = "_", arrays) { function combine(accum, prefix, remainingArrays) { if (!remainingArrays.length && prefix != null) { accum.push(prefix); return; } const array = remainingArrays[0]; const newRemainingArrays = remainingArrays.slice(1); for (const item of array) { combine(accum, prefix == null ? item : `${prefix}${separator}${item}`, newRemainingArrays); } } const result = []; combine(result, null, arrays); return result; } export { pivotWider }; //# sourceMappingURL=pivotWider.js.map