import {compose, cond, flatMap, identity, isDefined} from 'tsfun';
import {reduce} from 'tsfun/associative';
import {CsvExportUtils} from './csv-export-utils';
import {HeadingsAndMatrix} from './csv-export-consts';
const EMPTY = '';
/**
* @author Daniel de Oliveira
*/
export module CSVExpansion {
/**
* as: [A,B,C,D,E]
* where: 2
* nrOfNewItems: 2
* widthOfEachNewItem: 2
* ->
* [A,B,R1a,R1b,R2a,R2b,E]
*
* computeReplacement should return an array of size widthOfEachNewItem
*/
export function expandHomogeneousItems(computeReplacement: (removed: any) => any[],
widthOfEachNewItem: number) {
return (where: number, nrOfNewItems: number): (as: Array) => Array => {
return CsvExportUtils.replaceItems(
where,
nrOfNewItems,
flatMap(compose(
cond(isDefined, computeReplacement, []),
CsvExportUtils.fillUpToSize(widthOfEachNewItem, EMPTY))));
}
}
/**
* Expands headingsAndMatrix at the columns given by columnIndices, assuming that
* these columns contain array values, which in turn are objects.
*
* For example:
*
* [['h1', 'h2'],
* [[7, [{b: 2}, {b: 3}],
* [8, [{b: 5}]]]
*
* Expanding at index 1, with appropriate expansion functions we can transform into
*
* [['h1', 'h2.0.b', 'h2.1.b'],
* [[7, 2 , 3],
* [8, 5, , undefined]]]
*/
export function objectArrayExpand(headingsAndMatrix: HeadingsAndMatrix,
expandHeadings: (numItems: number) => (fieldName: string) => string[],
expandObject: (where: number, nrOfNewItems: number) => (itms: any[]) => any[])
: (columnIndices: number[]) => HeadingsAndMatrix {
return reduce(([headings, matrix]: HeadingsAndMatrix, columnIndex: number) => {
const max = Math.max(1, CsvExportUtils.getMax(columnIndex)(matrix));
const expandedHeader = CsvExportUtils.replaceItem(columnIndex, expandHeadings(max))(headings);
const expandedRows = matrix
.map(expandArray(columnIndex, max))
.map(expandObject(columnIndex, max));
return [expandedHeader, expandedRows];
}, headingsAndMatrix);
}
export function objectExpand(headingsAndMatrix: HeadingsAndMatrix,
expandHeadings: (fieldName: string) => string[],
expandObject: (where: number, nrOfNewItems: number) => (itms: any[]) => any[])
: (columnIndices: number[]) => HeadingsAndMatrix {
return reduce(([headings, matrix]: HeadingsAndMatrix, columnIndex: number) => {
const expandedHeader = CsvExportUtils.replaceItem(columnIndex, expandHeadings)(headings);
const expandedRows = matrix.map(expandObject(columnIndex, 1));
return [expandedHeader, expandedRows];
}, headingsAndMatrix);
}
function expandArray(columnIndex: number, widthOfNewItem: number) {
return CSVExpansion.expandHomogeneousItems(identity, widthOfNewItem)(columnIndex, 1);
}
}