import { isEqual } from '@antv/util'; /** * 比较两个数组的差异 * * compare the difference between two arrays * @param original - 原始数组 | original array * @param modified - 修改后的数组 | modified array * @param key - 比较的 key | key to compare * @param comparator - 比较函数 | compare function * @returns 数组差异 | array diff */ export function arrayDiff( original: T[], modified: T[], key: (d: T) => string | number, comparator: (a?: T, b?: T) => boolean = isEqual, ) { const originalMap = new Map(original.map((d) => [key(d), d])); const modifiedMap = new Map(modified.map((d) => [key(d), d])); const originalSet = new Set(originalMap.keys()); const modifiedSet = new Set(modifiedMap.keys()); const enter: T[] = []; const update: T[] = []; const exit: T[] = []; const keep: T[] = []; modifiedSet.forEach((key) => { if (originalSet.has(key)) { if (!comparator(originalMap.get(key), modifiedMap.get(key))) { update.push(modifiedMap.get(key)!); } else { keep.push(modifiedMap.get(key)!); } } else { enter.push(modifiedMap.get(key)!); } }); originalSet.forEach((key) => { if (!modifiedSet.has(key)) { exit.push(originalMap.get(key)!); } }); return { enter, exit, keep, update }; }