import get from "lodash/get"; import isFunction from "lodash/isFunction"; import setWith from "lodash/setWith"; import updateWith from "lodash/updateWith"; export const apply = (source, [path, value]) => { const handle = isFunction(value) ? updateWith : setWith; return handle(source, path, value, Object); }; export const assign = (source, transformations = []) => transformations.reduce(apply, source); export const extract = ({ columns, rows }) => [].concat(rows.slice(0, rows.length - 1), columns, rows.slice(-1)); export const process = ({ data, settings }) => { console.clear(); console.time("process"); const fields = extract(settings); const scan = (input, record) => { const iterate = (output, type, index) => { const { [type]: property } = record; const content = String(property).trim(); const restore = (cache) => cache || { content, type, details: [] }; const folder = output.path.tree.concat(!!index ? "details" : []); const indexes = output.path.indexes.concat(content); const { length } = get(output.input, folder); const path = get(output.input, indexes, length); const tree = folder.concat(path); return { input: assign(output.input, [ [indexes, path], [tree, restore], ]), path: { indexes, tree }, }; }; return fields.reduce(iterate, { path: { indexes: ["indexes"], tree: ["tree"] }, input, }).input; }; const response = data.reduce(scan, { indexes: {}, tree: [] }); console.timeEnd("process"); return response.tree; };