Skip to content

Commit

Permalink
feat(relate): add method to dedupe dobjs by identity
Browse files Browse the repository at this point in the history
  • Loading branch information
uladkasach committed Apr 28, 2024
1 parent 40b4e88 commit ef13b1e
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/manipulation/relate/dedupe.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { DomainEntity } from '../../instantiation/DomainEntity';
import { DomainValueObject } from '../../instantiation/DomainValueObject';
import { dedupe } from './dedupe';

describe('dedupe', () => {
interface SeaTurtle {
saltwaterSecurityNumber: string;
name: string;
}
class SeaTurtle extends DomainEntity<SeaTurtle> implements SeaTurtle {
public static unique = ['saltwaterSecurityNumber'];
}

interface Region {
name: string;
}
class Region extends DomainValueObject<Region> implements Region {}

// some entities with a dupe
const turtleOne = new SeaTurtle({
saltwaterSecurityNumber: '821',
name: 'Shelly C.',
});
const turtleTwo = new SeaTurtle({
saltwaterSecurityNumber: '921',
name: 'Shellbert',
});
const turtleOneAlias = new SeaTurtle({
...turtleOne,
name: 'Shellina C.',
});

// some value objects with a dupe
const regionOne = new Region({
name: 'Great Barrier Reef',
});
const regionTwo = new Region({
name: 'Puerto Rico Trench',
});
const regionThree = new Region({
name: 'East Pacific',
});

it('should keep only the one instance per distinct identity', () => {
const deduped = dedupe([
// entities
turtleOne,
turtleTwo,
turtleTwo, // exact dupe
turtleOneAlias, // identity dupe
turtleTwo, // exact dupe
regionOne,
regionThree,
regionTwo,
regionTwo,
regionOne,
]);
expect(deduped).toHaveLength(5);
});
it('should keep only the first instance per distinct identity', () => {
const deduped = dedupe([
turtleOne, // exact dupe
turtleOneAlias, // identity dupe
turtleOne, // exact dupe
turtleOneAlias, // identity dupe
]);
expect(deduped).toHaveLength(1);
expect(deduped[0].name).toEqual('Shelly C.');
});
});
15 changes: 15 additions & 0 deletions src/manipulation/relate/dedupe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DomainObject } from '../../instantiation/DomainObject';
import { getUniqueIdentifier } from '../getUniqueIdentifier';
import { serialize } from '../serde/serialize';

export const dedupe = <T extends DomainObject<Record<string, any>>>(
objs: T[],
): T[] =>
objs.filter((thisObj, thisIndex) => {
const indexOfFirstOccurrence = objs.findIndex(
(otherObj) =>
serialize(getUniqueIdentifier(thisObj)) ===
serialize(getUniqueIdentifier(otherObj)),
);
return indexOfFirstOccurrence === thisIndex; // if this index is the same as its first index, then keep it; otherwise, its a dupe
});

0 comments on commit ef13b1e

Please sign in to comment.