diff.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // type Diff<T = any> = T;
  2. // 比较两个数组是否相等
  3. function arraysEqual<T>(a: T[], b: T[]): boolean {
  4. if (a.length !== b.length) return false;
  5. const counter = new Map<T, number>();
  6. for (const value of a) {
  7. counter.set(value, (counter.get(value) || 0) + 1);
  8. }
  9. for (const value of b) {
  10. const count = counter.get(value);
  11. if (count === undefined || count === 0) {
  12. return false;
  13. }
  14. counter.set(value, count - 1);
  15. }
  16. return true;
  17. }
  18. // 深度对比两个值
  19. // function deepEqual<T>(oldVal: T, newVal: T): boolean {
  20. // if (
  21. // typeof oldVal === 'object' &&
  22. // oldVal !== null &&
  23. // typeof newVal === 'object' &&
  24. // newVal !== null
  25. // ) {
  26. // return Array.isArray(oldVal) && Array.isArray(newVal)
  27. // ? arraysEqual(oldVal, newVal)
  28. // : diff(oldVal as any, newVal as any) === null;
  29. // } else {
  30. // return oldVal === newVal;
  31. // }
  32. // }
  33. // // diff 函数
  34. // function diff<T extends object>(
  35. // oldObj: T,
  36. // newObj: T,
  37. // ignoreFields: (keyof T)[] = [],
  38. // ): { [K in keyof T]?: Diff<T[K]> } | null {
  39. // const difference: { [K in keyof T]?: Diff<T[K]> } = {};
  40. // for (const key in oldObj) {
  41. // if (ignoreFields.includes(key)) continue;
  42. // const oldValue = oldObj[key];
  43. // const newValue = newObj[key];
  44. // if (!deepEqual(oldValue, newValue)) {
  45. // difference[key] = newValue;
  46. // }
  47. // }
  48. // return Object.keys(difference).length === 0 ? null : difference;
  49. // }
  50. type DiffResult<T> = Partial<{
  51. [K in keyof T]: T[K] extends object ? DiffResult<T[K]> : T[K];
  52. }>;
  53. function diff<T extends Record<string, any>>(obj1: T, obj2: T): DiffResult<T> {
  54. function findDifferences(o1: any, o2: any): any {
  55. if (Array.isArray(o1) && Array.isArray(o2)) {
  56. if (!arraysEqual(o1, o2)) {
  57. return o2;
  58. }
  59. return undefined;
  60. }
  61. if (
  62. typeof o1 === 'object' &&
  63. typeof o2 === 'object' &&
  64. o1 !== null &&
  65. o2 !== null
  66. ) {
  67. const diffResult: any = {};
  68. const keys = new Set([...Object.keys(o1), ...Object.keys(o2)]);
  69. keys.forEach((key) => {
  70. const valueDiff = findDifferences(o1[key], o2[key]);
  71. if (valueDiff !== undefined) {
  72. diffResult[key] = valueDiff;
  73. }
  74. });
  75. return Object.keys(diffResult).length > 0 ? diffResult : undefined;
  76. }
  77. return o1 === o2 ? undefined : o2;
  78. }
  79. return findDifferences(obj1, obj2);
  80. }
  81. export { arraysEqual, diff };