Skip to content

Instantly share code, notes, and snippets.

@tinncdev
Last active August 3, 2021 04:51
Show Gist options
  • Save tinncdev/ec244f013c69d17eb5b7039a78406d68 to your computer and use it in GitHub Desktop.
Save tinncdev/ec244f013c69d17eb5b7039a78406d68 to your computer and use it in GitHub Desktop.
categorize added/updated/deleted/unchanged items from 2 set
function diff<T>(
currentItems: T[],
newItems: T[],
identifier: (item: T) => any,
equalComparator: (item1: T, item2: T) => boolean,
): { added: T[], updated: T[], deleted: T[], unchanged: T[] } {
const added: T[] = [];
const updated: T[] = [];
const deleted: T[] = [];
const unchanged: T[] = [];
const currentItemIds = currentItems.map(i => identifier(i));
const newItemIds = newItems.map(i => identifier(i));
newItemIds.forEach((itemId, index) => {
const currentItemIdIndex = itemId ? currentItemIds.indexOf(itemId) : -1;
const isNewItem = currentItemIdIndex < 0;
if (isNewItem) {
added.push(newItems[index]);
} else {
const currentItemVersion = currentItems[currentItemIdIndex];
const isChanged = !equalComparator(currentItemVersion, newItems[index]);
if (isChanged) {
updated.push(newItems[index]);
} else {
unchanged.push(currentItemVersion);
}
}
});
currentItems.forEach((itemId, index) => {
const newItemIndex = newItemIds.indexOf(itemId);
const hasItemBeenDeleted = newItemIndex < 0;
if (hasItemBeenDeleted) {
deleted.push(currentItems[index]);
}
});
return { added, updated, deleted, unchanged };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment