The original code looks more like traditional JS, it does not benefit from typing features provided by the TypeScript language.
The solution I suggest below is not necessarily shorter, but its main goal is to put the things in order using the TS style.
First of all, interfaces can be created to define the structures of the data
and limit
objects:
interface MyDataItem {
val1: Array<number>;
val2: Array<number>;
};
interface Limit {
minX: number;
maxX: number;
minY: number;
maxY: number;
};
To access the val1
and val2
properties generically, a type and respective constants can be defined:
type PropertyAccessor = (item: MyDataItem) => Array<number>;
const accessorX: PropertyAccessor = item => item.val1;
const accessorY: PropertyAccessor = item => item.val2;
Similarly, to access the min
and max
values, we can define dedicated mapping constants:
type ValueExtractor = (values: Array<number>) => number;
const extractorMin: ValueExtractor = values => Math.min(...values);
const extractorMax: ValueExtractor = values => Math.max(...values);
Now, the implementation of the determineMinMax
function becomes very concise and does not include repetitive stuff:
const determineMinMax = (data: Array<MyDataItem>): Limit => ({
minX: extractMinMax(data, accessorX, extractorMin),
maxX: extractMinMax(data, accessorX, extractorMax),
minY: extractMinMax(data, accessorY, extractorMin),
maxY: extractMinMax(data, accessorY, extractorMax)
});
Finally, we need to implement the extractMinMax
function, which contains the main calculation logic:
const extractMinMax = (data: Array<MyDataItem>,
propertyAccessor: PropertyAccessor,
minMaxExtractor: ValueExtractor): number =>
data.map(propertyAccessor) // extract the array with the current property from data
.map(minMaxExtractor) // find the min value of each property
.reduce((prev: number, next: number) => minMaxExtractor([prev, next])); // find the min value among all min values
...and a test case checking the calculated value:
describe('Q268329', () => {
it('should return expected value', () => {
const data = [
{val1: [1,2,3,4], val2:[6,7,8,9] }
];
const limit = determineMinMax(data);
expect(limit).toEqual({
minX: 1, maxX: 4, minY: 6, maxY: 9
});
});
});