effect icon indicating copy to clipboard operation
effect copied to clipboard

No duplicates array filter

Open parischap opened this issue 2 years ago • 1 comments

🚀 Feature request

Current Behavior

You often need to use an array of structs to describe your data, e.g. an array of users or posts. You may then need to check that the user ID is unique. In general, it can be necessary to check that a sub-set of the columns of the array form a unique key.

Desired Behavior

Proposal to add a noDups array filter.

Suggested Solution

export const noDups = <C>(isEquivalent: (self: C, that: C) => boolean) =>
	S.filter<ReadonlyArray<C>>(
		(a) => pipe(a, RA.uniq(isEquivalent), (a1) => a1.length === a.length),
		{
			message: (a) => 'No duplicates allowed'
		}
	);

Use example:

import * as S from '@effect/schema/Schema';
import { formatErrors } from '@effect/schema/TreeFormatter';
import { ES } from 'mjljm-effect-lib';
const e = pipe(
	S.array(S.struct({ a: S.number, b: S.number, c: S.number })),
	ES.noDups((e1, e2) => e1.a === e2.a)
);

const p = S.parseEither(e);
const result = p([
	{ a: 2, b: 1, c: 3 },
	{ a: 1, b: 1, c: 1 },
	{ a: 3, b: 2, c: 3 }
]);
if (E.isLeft(result)) {
	console.error('Parsing failed:');
	console.error(formatErrors(result.left.errors));
} else console.log(result.right);

Who does this impact? Who is this for?

Describe alternatives you've considered

None

Additional context

Your environment

Software Version(s)
@effect/schema 0.20.1
TypeScript 5.1.3

parischap avatar Jun 14 '23 07:06 parischap

+1 A "dedup" transform might be useful as well that actually removes duplicates.

jessekelly881 avatar Jun 14 '23 18:06 jessekelly881