Skip to content

Commit

Permalink
arrayDiff filter duplicates
Browse files Browse the repository at this point in the history
  • Loading branch information
dabbott committed Dec 18, 2023
1 parent 2a17d98 commit 704602d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/noya-component/src/__tests__/arrayDiff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,13 @@ test('swaps multiple pairs', () => {
expect(applied).toEqual(b);
expect(diff).toEqual([moved(0, 1), moved(4, 5)]);
});

test('filter duplicates', () => {
let a = ['a'];
let b = ['a', 'a', 'b'];

const diff = computeArrayDiff(a, b);
const applied = applyArrayDiff(a, diff);

expect(applied).toEqual(['a', 'b']);
});
17 changes: 17 additions & 0 deletions packages/noya-component/src/arrayDiff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ function computeFirstArrayMove<T>(
}
}

function filterDuplicates<T>(
a: T[],
identity: (item: T) => unknown = (item) => item,
): T[] {
const map = new Map(a.map((item, index) => [identity(item), index]));

return [...map.values()].map((index) => a[index]);
}

export function computeArrayDiff<T>(a: T[], b: T[]): ArrayDiffItem<T>[];
export function computeArrayDiff<T, K>(
a: T[],
Expand All @@ -52,6 +61,14 @@ export function computeArrayDiff<T>(
const aMap = new Map(a.map((item, index) => [identity(item), index]));
const bMap = new Map(b.map((item, index) => [identity(item), index]));

// Detect duplicates by comparing array length vs map size.
if (aMap.size !== a.length || bMap.size !== b.length) {
return computeArrayDiff(
filterDuplicates(a, identity),
filterDuplicates(b, identity),
);
}

// Check for removed items.
let removalOffset = 0;
for (let i = 0; i < a.length; i++) {
Expand Down

0 comments on commit 704602d

Please sign in to comment.