import { isUndefined } from "../../util/isUndefined"; type KeyFn = (item: T) => any; interface DiffResult { added: T[]; changed: { before: T; after: T }[]; unchanged: T[]; removed: T[]; } export function diffArrays(oldArray: T[], newArray: T[], keyFn: KeyFn = (e) => e): DiffResult { const map = new Map(); oldArray.forEach((item) => { const key = keyFn(item); map.set(key, item); }); const added: T[] = []; const changed: { before: T; after: T }[] = []; const unchanged: T[] = []; newArray.forEach((item) => { const key = keyFn(item); const oldItem = map.get(key); if (isUndefined(oldItem)) { added.push(item); } else { map.delete(key); if (item === oldItem) { unchanged.push(item); } else { changed.push({ before: oldItem, after: item }); } } }); const removed = Array.from(map.values()); return { added, changed, unchanged, removed, }; }