UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

101 lines (100 loc) 3.58 kB
import { DeepMap } from './deepMap'; function DEFAULT_TO_KEY(value) { return value; } export function group(groupParams, data) { const { groupBy, defaultToKey = DEFAULT_TO_KEY, reducers } = groupParams; const groupByLength = groupBy.length; const deepMap = new DeepMap(); let currentGroupKeys = []; const initialReducerValue = initReducers(reducers); const globalReducerResults = { ...initialReducerValue }; for (let i = 0, len = data.length; i < len; i++) { let item = data[i]; for (let groupByIndex = 0; groupByIndex < groupByLength; groupByIndex++) { const { field: groupByProperty, toKey: groupToKey } = groupBy[groupByIndex]; const key = (groupToKey || defaultToKey)(item[groupByProperty], item); currentGroupKeys.push(key); if (!deepMap.has(currentGroupKeys)) { const deepMapGroupValue = { items: [], reducerResults: { ...initialReducerValue }, }; deepMap.set(currentGroupKeys, deepMapGroupValue); } const { items: currentGroupItems, reducerResults } = deepMap.get(currentGroupKeys); currentGroupItems.push(item); if (reducers) { computeReducersFor(item, reducers, reducerResults); } } if (reducers) { computeReducersFor(item, reducers, globalReducerResults); } currentGroupKeys.length = 0; } const hasReducersWithDoneFn = reducers && Object.values(reducers).some((reducer) => reducer.done); if (hasReducersWithDoneFn) { deepMap.visitDepthFirst((deepMapValue, _keys, _indexInGroup, next) => { completeReducers(reducers, deepMapValue.reducerResults, deepMapValue.items); next?.(); }); } if (hasReducersWithDoneFn) { completeReducers(reducers, globalReducerResults, data); } const result = { deepMap, groupParams, initialData: data, reducerResults: globalReducerResults, }; return result; } function initReducers(reducers) { if (!reducers || !Object.keys(reducers).length) { return {}; } const result = {}; for (let key in reducers) if (reducers.hasOwnProperty(key)) { result[key] = reducers[key].initialValue; } return result; } /** * * This fn mutates the reducerResults array!!! * * @param data data item * @param reducers an array of reducers * @param reducerResults the results on which to operate * */ function computeReducersFor(data, reducers, reducerResults) { if (!reducers || !Object.keys(reducers).length) { return; } for (let key in reducers) if (reducers.hasOwnProperty(key)) { const reducer = reducers[key]; if (typeof reducer.reducer !== 'function') { continue; } const currentValue = reducerResults[key]; const value = reducer.field ? data[reducer.field] : reducer.getter?.(data) ?? null; reducerResults[key] = reducer.reducer(currentValue, value, data); } } function completeReducers(reducers, reducerResults, items) { if (reducers) { for (let key in reducers) if (reducers.hasOwnProperty(key)) { const reducer = reducers[key]; if (reducer.done) { reducerResults[key] = reducer.done(reducerResults[key], items); } } } return reducerResults; }