diff --git a/src/xy/__tests__/xyFilter.test.ts b/src/xy/__tests__/xyFilter.test.ts new file mode 100644 index 00000000..b6b0dca9 --- /dev/null +++ b/src/xy/__tests__/xyFilter.test.ts @@ -0,0 +1,35 @@ +import { xyFilter } from '../../index'; + +describe('xyFilter', () => { + const x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + const y = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; + const points = { x, y }; + + it('no filter', () => { + const result = xyFilter(points); + expect(result).toStrictEqual({ + x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + y: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], + }); + }); + + it('x filter', () => { + const result = xyFilter(points, { + filter: (xValue) => xValue <= 2 || xValue >= 5, + }); + expect(result).toStrictEqual({ + x: [0, 1, 2, 5, 6, 7, 8, 9, 10], + y: [1, 2, 3, 6, 7, 8, 9, 10, 11], + }); + }); + + it('y filter', () => { + const result = xyFilter(points, { + filter: (xValue, yValue) => yValue <= 2 || yValue >= 5, + }); + expect(result).toStrictEqual({ + x: [0, 1, 4, 5, 6, 7, 8, 9, 10], + y: [1, 2, 5, 6, 7, 8, 9, 10, 11], + }); + }); +}); diff --git a/src/xy/index.ts b/src/xy/index.ts index 65a663a5..67fe6cc9 100644 --- a/src/xy/index.ts +++ b/src/xy/index.ts @@ -6,6 +6,7 @@ export * from './xyCumulativeDistributionStatistics'; export * from './xyEnsureGrowingX'; export * from './xyEquallySpaced'; export * from './xyExtract'; +export * from './xyFilter'; export * from './xyFilterMinYValue'; export * from './xyFilterTopYValues'; export * from './xyFilterX'; diff --git a/src/xy/xyFilter.ts b/src/xy/xyFilter.ts new file mode 100644 index 00000000..e19fa858 --- /dev/null +++ b/src/xy/xyFilter.ts @@ -0,0 +1,33 @@ +import { DataXY } from 'cheminfo-types'; + +export interface XYFilterOptions { + /** callback + * @default ()=>true + */ + filter?: (x: number, y: number) => boolean; +} + +/** Filter an array x/y based on various criteria x points are expected to be sorted + * + * @param data - object containing 2 properties x and y + * @param options - options + * @return filtered array + */ +export function xyFilter(data: DataXY, options: XYFilterOptions = {}): DataXY { + const { x, y } = data; + const { filter } = options; + const newX = []; + const newY = []; + + for (let i = 0; i < x.length; i++) { + if (!filter || filter(x[i], y[i])) { + newX.push(x[i]); + newY.push(y[i]); + } + } + + return { + x: newX, + y: newY, + }; +}