Skip to content

Instantly share code, notes, and snippets.

@marcelmokos
Created March 10, 2023 00:18
Show Gist options
  • Save marcelmokos/97124b7bbd9708bc554339846851d78b to your computer and use it in GitHub Desktop.
Save marcelmokos/97124b7bbd9708bc554339846851d78b to your computer and use it in GitHub Desktop.
/** * Computes the changes between two lists of items. * @param prev The previous list of items. * @param curr The current list of items. * @param isEqual The comparison function to use to determine if two items are deep equal. * @returns An object containing three properties: * - add: the items that were added to the current list. * - update: t…
import isEqualFn from 'lodash/fp/isEqual';
type Item = { id: string | number };
/**
* Computes the changes between two lists of items.
* @param prev The previous list of items.
* @param curr The current list of items.
* @param isEqual The comparison function to use to determine if two items are deep equal.
* @returns An object containing three properties:
* - add: the items that were added to the current list.
* - update: the items that were updated in the current list.
* - remove: the items that were removed from the current list.
*/
export const getChangesOnList = <I extends Item>(
prev: I[],
curr: I[],
isEqual = isEqualFn
) => {
const prevMap = new Map(prev.map((item) => [item.id, item]));
const currSet = new Set(curr.map((item) => item.id));
const metrics: {
add: I[];
update: I[];
remove: I[];
} = {
add: [],
update: [],
remove: prev.filter((item) => !currSet.has(item.id)),
};
return curr.reduce((acc, item) => {
if (!prevMap.has(item.id)) {
return {
...acc,
add: [...acc.add, item],
};
}
const prevItem = prevMap.get(item.id);
if (isEqual(prevItem, item)) {
return acc;
}
return {
...acc,
update: [...acc.update, item],
};
}, metrics);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment