Skip to content

Commit 4cd41a9

Browse files
committed
feat: add xyObjectMinMaxValues function
1 parent 727a0d4 commit 4cd41a9

File tree

8 files changed

+103
-7
lines changed

8 files changed

+103
-7
lines changed

src/__tests__/__snapshots__/index.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ exports[`test existence of exported functions 1`] = `
125125
"xyObjectJoinX",
126126
"xyObjectMaxXPoint",
127127
"xyObjectMaxYPoint",
128+
"xyObjectMinMaxValues",
128129
"xyObjectMinXPoint",
129130
"xyObjectMinYPoint",
130131
"xyObjectSlotX",

src/x/xCheck.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import type { NumberArray } from 'cheminfo-types';
22
import { isAnyArray } from 'is-any-array';
33

44
export interface XCheckOptions {
5-
/** minimum length */
5+
/**
6+
* Minimum length
7+
* @default 1
8+
*/
69
minLength?: number;
710
}
811

912
/**
10-
* Checks if input is of type array.
11-
* @param input - input
12-
* @param options
13+
* Checks if the input is a non-empty array of numbers.
14+
* Only checks the first element.
15+
* @param input - Array to check.
16+
* @param options - Additional checks.
1317
*/
1418
export function xCheck(
1519
input?: NumberArray,

src/x/xMinMaxValues.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { xCheck } from './xCheck';
55
/**
66
* Return min and max values of an array.
77
* @param array - array of number
8-
* @returns - Object with 2 properties, min and max
8+
* @returns - Object with 2 properties, min and max.
99
*/
1010
export function xMinMaxValues(array: NumberArray): {
1111
min: number;

src/xyObject/__tests__/xyObjectCheck.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,16 @@ test('xyObjectCheck', () => {
1212
expect(() => xyObjectCheck('a')).toThrow(
1313
'points must be an array of {x,y} objects',
1414
);
15+
expect(
16+
xyObjectCheck(
17+
[
18+
{ x: 0, y: 1 },
19+
{ x: 2, y: 3 },
20+
],
21+
{ minLength: 2 },
22+
),
23+
).toBeUndefined();
24+
expect(() => xyObjectCheck([{ x: 0, y: 1 }], { minLength: 2 })).toThrow(
25+
'points must have a length of at least 2',
26+
);
1527
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect, test } from 'vitest';
2+
3+
import { xyObjectMinMaxValues } from '../xyObjectMinMaxValues';
4+
5+
test('one element', () => {
6+
expect(xyObjectMinMaxValues([{ x: 1, y: 2 }])).toStrictEqual({
7+
minX: 1,
8+
maxX: 1,
9+
minY: 2,
10+
maxY: 2,
11+
});
12+
});
13+
14+
test('multiple elements', () => {
15+
expect(
16+
xyObjectMinMaxValues([
17+
{ x: 1, y: 2 },
18+
{ x: 5, y: 4 },
19+
{ x: 3, y: 6 },
20+
{ x: -2, y: -5 },
21+
{ x: 0, y: 0 },
22+
]),
23+
).toStrictEqual({ minX: -2, maxX: 5, minY: -5, maxY: 6 });
24+
});
25+
26+
test('throws error if array is empty', () => {
27+
expect(() => xyObjectMinMaxValues([])).toThrow(
28+
'points must have a length of at least 1',
29+
);
30+
});

src/xyObject/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from './xyObjectCheck';
33
export * from './xyObjectJoinX';
44
export * from './xyObjectMaxXPoint';
55
export * from './xyObjectMaxYPoint';
6+
export * from './xyObjectMinMaxValues';
67
export * from './xyObjectMinXPoint';
78
export * from './xyObjectMinYPoint';
89
export * from './xyObjectSlotX';

src/xyObject/xyObjectCheck.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
import type { Point } from '../types';
22

3+
export interface XYObjectCheckOptions {
4+
/**
5+
* Minimum length
6+
* @default 0
7+
*/
8+
minLength?: number;
9+
}
10+
311
/**
4-
* Throws an error in not an array of x,y objects.
12+
* Throws an error if it's not an array of x,y objects.
13+
* Only checks the first element.
514
* @param points - List of points.
15+
* @param options - Additional checks.
616
*/
7-
export function xyObjectCheck(points?: Point[]): asserts points is Point[] {
17+
export function xyObjectCheck(
18+
points?: Point[],
19+
options: XYObjectCheckOptions = {},
20+
): asserts points is Point[] {
21+
const { minLength = 0 } = options;
822
if (!Array.isArray(points)) {
923
throw new Error('points must be an array of {x,y} objects');
1024
}
@@ -14,4 +28,7 @@ export function xyObjectCheck(points?: Point[]): asserts points is Point[] {
1428
) {
1529
throw new Error('points must be an array of {x,y} objects');
1630
}
31+
if (minLength && points.length < minLength) {
32+
throw new Error(`points must have a length of at least ${minLength}`);
33+
}
1734
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { Point } from '../types';
2+
3+
import { xyObjectCheck } from './xyObjectCheck';
4+
5+
/**
6+
* Returns all min and max values of an array of points.
7+
* @param points - Array of points {x,y}.
8+
* @returns - Object with the 4 extrema.
9+
*/
10+
export function xyObjectMinMaxValues(points: Point[]): {
11+
minX: number;
12+
maxX: number;
13+
minY: number;
14+
maxY: number;
15+
} {
16+
xyObjectCheck(points, { minLength: 1 });
17+
18+
let minX = points[0].x;
19+
let maxX = minX;
20+
let minY = points[0].y;
21+
let maxY = minY;
22+
23+
for (const point of points) {
24+
if (point.x < minX) minX = point.x;
25+
if (point.x > maxX) maxX = point.x;
26+
if (point.y < minY) minY = point.y;
27+
if (point.y > maxY) maxY = point.y;
28+
}
29+
30+
return { minX, maxX, minY, maxY };
31+
}

0 commit comments

Comments
 (0)