function parseBicycleCountRow(row, { header, orientationIndexes, flatten = false }) {
const [startTimeRaw, ...rowValues] = row.split(',');
const startTime = new Date(startTimeRaw);
const rowValuesWithLabels = rowValues.map((v, index) => {
const label = header[index + 1];
return { entry: [label, Number(v)], index };
});
const countsByOrientationGroups = _.groupBy(rowValuesWithLabels, ({ index }) => {
const { entry, direction } = orientationIndexes.find(({ indexes }) => indexes.includes(index));
return `${entry}_${direction}`.toLowerCase();
});
const orientationEntries = _.map(countsByOrientationGroups, (value, orientation) => {
const entries = _.map(value, 'entry');
const total = _.sum(entries.map(([key, count]) => count));
entries.push(['total', total]);
if (flatten) {
return _.map(entries, ([key, count]) => ([`${orientation}.${key}`, count]));
}
return [orientation, Object.fromEntries(entries)];
});
const countsByOrientation = Object.fromEntries(
flatten ? orientationEntries.flat() : orientationEntries
);
const total = _.sum(orientationEntries.flat().filter(([key, value]) => key.endsWith('.total')).map(([key, value]) => value));
return {
start_time: startTime,
total,
...countsByOrientation,
};
}