Skip to content

Instantly share code, notes, and snippets.

@mfal
Created June 12, 2019 15:08
Show Gist options
  • Save mfal/cd5d6e8d2e5dd335d4633ab92fff5b9f to your computer and use it in GitHub Desktop.
Save mfal/cd5d6e8d2e5dd335d4633ab92fff5b9f to your computer and use it in GitHub Desktop.
type CollectionDiff<TModified, TNew = TModified, TDeleted = TModified> = {
new: TNew[];
modified: TModified[];
deleted: TDeleted[];
};
export const calcCollectionDiff = <L, R = L>(
left: Iterable<L> | Array<L>,
right: Iterable<R> | Array<R>,
getLeftKey: (item: L) => string,
getRightKey: (item: R) => string,
areEqual: (leftItem: L, rightItem: R) => boolean,
) => {
const result: CollectionDiff<R, R, L> = {
new: [],
deleted: [],
modified: [],
};
const leftItemKeys: string[] = [];
for (const leftItem of left) {
const leftItemKey = getLeftKey(leftItem);
leftItemKeys.push(leftItemKey);
let found = false;
for (const righItem of right) {
const rightItemKey = getRightKey(righItem);
if (rightItemKey === leftItemKey) {
found = true;
if (!areEqual(leftItem, righItem)) {
result.modified.push(righItem);
}
break;
}
}
if (!found) {
result.deleted.push(leftItem);
}
}
for (const rightItem of right) {
const rightItemKey = getRightKey(rightItem);
if (leftItemKeys.indexOf(rightItemKey) === -1) {
result.new.push(rightItem);
}
}
return result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment