Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add xyObjectMinMaxValues function #279

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/__tests__/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ exports[`test existence of exported functions 1`] = `
"xyObjectJoinX",
"xyObjectMaxXPoint",
"xyObjectMaxYPoint",
"xyObjectMinMaxValues",
"xyObjectMinXPoint",
"xyObjectMinYPoint",
"xyObjectSlotX",
Expand Down
12 changes: 8 additions & 4 deletions src/x/xCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ import type { NumberArray } from 'cheminfo-types';
import { isAnyArray } from 'is-any-array';

export interface XCheckOptions {
/** minimum length */
/**
* Minimum length
* @default 1
*/
minLength?: number;
}

/**
* Checks if input is of type array.
* @param input - input
* @param options
* Checks if the input is a non-empty array of numbers.
* Only checks the first element.
* @param input - Array to check.
* @param options - Additional checks.
*/
export function xCheck(
input?: NumberArray,
Expand Down
2 changes: 1 addition & 1 deletion src/x/xMinMaxValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { xCheck } from './xCheck';
/**
* Return min and max values of an array.
* @param array - array of number
* @returns - Object with 2 properties, min and max
* @returns - Object with 2 properties, min and max.
*/
export function xMinMaxValues(array: NumberArray): {
min: number;
Expand Down
12 changes: 12 additions & 0 deletions src/xyObject/__tests__/xyObjectCheck.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,16 @@ test('xyObjectCheck', () => {
expect(() => xyObjectCheck('a')).toThrow(
'points must be an array of {x,y} objects',
);
expect(
xyObjectCheck(
[
{ x: 0, y: 1 },
{ x: 2, y: 3 },
],
{ minLength: 2 },
),
).toBeUndefined();
expect(() => xyObjectCheck([{ x: 0, y: 1 }], { minLength: 2 })).toThrow(
'points must have a length of at least 2',
);
});
30 changes: 30 additions & 0 deletions src/xyObject/__tests__/xyObjectMinMaxValues.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { expect, test } from 'vitest';

import { xyObjectMinMaxValues } from '../xyObjectMinMaxValues';

test('one element', () => {
expect(xyObjectMinMaxValues([{ x: 1, y: 2 }])).toStrictEqual({
minX: 1,
maxX: 1,
minY: 2,
maxY: 2,
});
});

test('multiple elements', () => {
expect(
xyObjectMinMaxValues([
{ x: 1, y: 2 },
{ x: 5, y: 4 },
{ x: 3, y: 6 },
{ x: -2, y: -5 },
{ x: 0, y: 0 },
]),
).toStrictEqual({ minX: -2, maxX: 5, minY: -5, maxY: 6 });
});

test('throws error if array is empty', () => {
expect(() => xyObjectMinMaxValues([])).toThrow(
'points must have a length of at least 1',
);
});
1 change: 1 addition & 0 deletions src/xyObject/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './xyObjectCheck';
export * from './xyObjectJoinX';
export * from './xyObjectMaxXPoint';
export * from './xyObjectMaxYPoint';
export * from './xyObjectMinMaxValues';
export * from './xyObjectMinXPoint';
export * from './xyObjectMinYPoint';
export * from './xyObjectSlotX';
Expand Down
21 changes: 19 additions & 2 deletions src/xyObject/xyObjectCheck.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import type { Point } from '../types';

export interface XYObjectCheckOptions {
/**
* Minimum length
* @default 0
*/
minLength?: number;
}

/**
* Throws an error in not an array of x,y objects.
* Throws an error if it's not an array of x,y objects.
* Only checks the first element.
* @param points - List of points.
* @param options - Additional checks.
*/
export function xyObjectCheck(points?: Point[]): asserts points is Point[] {
export function xyObjectCheck(
points?: Point[],
options: XYObjectCheckOptions = {},
): asserts points is Point[] {
const { minLength = 0 } = options;
if (!Array.isArray(points)) {
throw new Error('points must be an array of {x,y} objects');
}
Expand All @@ -14,4 +28,7 @@ export function xyObjectCheck(points?: Point[]): asserts points is Point[] {
) {
throw new Error('points must be an array of {x,y} objects');
}
if (minLength && points.length < minLength) {
throw new Error(`points must have a length of at least ${minLength}`);
}
}
31 changes: 31 additions & 0 deletions src/xyObject/xyObjectMinMaxValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Point } from '../types';

import { xyObjectCheck } from './xyObjectCheck';

/**
* Returns all min and max values of an array of points.
* @param points - Array of points {x,y}.
* @returns - Object with the 4 extrema.
*/
export function xyObjectMinMaxValues(points: Point[]): {
minX: number;
maxX: number;
minY: number;
maxY: number;
} {
lpatiny marked this conversation as resolved.
Show resolved Hide resolved
xyObjectCheck(points, { minLength: 1 });

let minX = points[0].x;
let maxX = minX;
let minY = points[0].y;
let maxY = minY;

for (const point of points) {
if (point.x < minX) minX = point.x;
if (point.x > maxX) maxX = point.x;
if (point.y < minY) minY = point.y;
if (point.y > maxY) maxY = point.y;
}

return { minX, maxX, minY, maxY };
}
Loading