From 333fe92f48ae9fbf169f53fbb6fe83a1b58895e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:01:56 +0000 Subject: [PATCH 1/6] Initial plan From 017abf8f9d0f51965526b97902a0b248def76c0e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:04:53 +0000 Subject: [PATCH 2/6] refactor: optimize diffKeys with Set operations --- source/data.ts | 22 +++++++++++++++------- test/data.spec.ts | 11 +++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/source/data.ts b/source/data.ts index 0733cee..b4b7cd4 100644 --- a/source/data.ts +++ b/source/data.ts @@ -134,14 +134,22 @@ export enum DiffStatus { } export function diffKeys(oldList: T[], newList: T[]) { + const oldSet = new Set(oldList), + newSet = new Set(newList); const map = {} as Record; - - for (const item of oldList) map[item] = DiffStatus.Old; - - for (const item of newList) { - map[item] ||= 0; - map[item] += DiffStatus.New; - } + const getDifference = (leftSet: Set, rightSet: Set) => + leftSet.difference?.(rightSet) || + new Set(Array.from(leftSet).filter(key => !rightSet.has(key))); + const getIntersection = (leftSet: Set, rightSet: Set) => + leftSet.intersection?.(rightSet) || + new Set(Array.from(leftSet).filter(key => rightSet.has(key))); + + for (const item of getDifference(oldSet, newSet)) + map[item] = DiffStatus.Old; + for (const item of getIntersection(oldSet, newSet)) + map[item] = DiffStatus.Same; + for (const item of getDifference(newSet, oldSet)) + map[item] = DiffStatus.New; return { map, diff --git a/test/data.spec.ts b/test/data.spec.ts index 819a7af..7a7d2bd 100644 --- a/test/data.spec.ts +++ b/test/data.spec.ts @@ -153,6 +153,17 @@ describe('Data', () => { }); }); + it('should ignore duplicate keys when comparing key arrays', () => { + expect(diffKeys(['a', 'a', 'b'], ['b', 'b', 'c', 'c'])).toEqual({ + map: { a: DiffStatus.Old, b: DiffStatus.Same, c: DiffStatus.New }, + group: { + [DiffStatus.Old]: [['a', DiffStatus.Old]], + [DiffStatus.Same]: [['b', DiffStatus.Same]], + [DiffStatus.New]: [['c', DiffStatus.New]] + } + }); + }); + it('should detect an Object whether is Array-like or not', () => { expect(likeArray(NaN)).toBe(false); expect(likeArray('a')).toBe(true); From 61b67cf3c22104cf2540280962fc0d8b4faa0883 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:06:54 +0000 Subject: [PATCH 3/6] chore: clarify set helper naming in diffKeys --- source/data.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/data.ts b/source/data.ts index b4b7cd4..d833f84 100644 --- a/source/data.ts +++ b/source/data.ts @@ -137,18 +137,18 @@ export function diffKeys(oldList: T[], newList: T[]) { const oldSet = new Set(oldList), newSet = new Set(newList); const map = {} as Record; - const getDifference = (leftSet: Set, rightSet: Set) => + const getSetDifference = (leftSet: Set, rightSet: Set) => leftSet.difference?.(rightSet) || new Set(Array.from(leftSet).filter(key => !rightSet.has(key))); - const getIntersection = (leftSet: Set, rightSet: Set) => + const getSetIntersection = (leftSet: Set, rightSet: Set) => leftSet.intersection?.(rightSet) || new Set(Array.from(leftSet).filter(key => rightSet.has(key))); - for (const item of getDifference(oldSet, newSet)) + for (const item of getSetDifference(oldSet, newSet)) map[item] = DiffStatus.Old; - for (const item of getIntersection(oldSet, newSet)) + for (const item of getSetIntersection(oldSet, newSet)) map[item] = DiffStatus.Same; - for (const item of getDifference(newSet, oldSet)) + for (const item of getSetDifference(newSet, oldSet)) map[item] = DiffStatus.New; return { From a3b3cbef92e01d6b8559f6dff4de0a5d19592036 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:08:15 +0000 Subject: [PATCH 4/6] perf: hoist diffKeys set helpers --- source/data.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/data.ts b/source/data.ts index d833f84..9123357 100644 --- a/source/data.ts +++ b/source/data.ts @@ -133,16 +133,18 @@ export enum DiffStatus { New = 1 } +const getSetDifference = (leftSet: Set, rightSet: Set) => + leftSet.difference?.(rightSet) || + new Set(Array.from(leftSet).filter(key => !rightSet.has(key))); + +const getSetIntersection = (leftSet: Set, rightSet: Set) => + leftSet.intersection?.(rightSet) || + new Set(Array.from(leftSet).filter(key => rightSet.has(key))); + export function diffKeys(oldList: T[], newList: T[]) { const oldSet = new Set(oldList), newSet = new Set(newList); const map = {} as Record; - const getSetDifference = (leftSet: Set, rightSet: Set) => - leftSet.difference?.(rightSet) || - new Set(Array.from(leftSet).filter(key => !rightSet.has(key))); - const getSetIntersection = (leftSet: Set, rightSet: Set) => - leftSet.intersection?.(rightSet) || - new Set(Array.from(leftSet).filter(key => rightSet.has(key))); for (const item of getSetDifference(oldSet, newSet)) map[item] = DiffStatus.Old; From 50177367ea623a4784920acd3ceb7bd8706d47b9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:25:56 +0000 Subject: [PATCH 5/6] refactor: use native set difference/intersection directly --- source/data.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/data.ts b/source/data.ts index 9123357..6036cdf 100644 --- a/source/data.ts +++ b/source/data.ts @@ -134,12 +134,10 @@ export enum DiffStatus { } const getSetDifference = (leftSet: Set, rightSet: Set) => - leftSet.difference?.(rightSet) || - new Set(Array.from(leftSet).filter(key => !rightSet.has(key))); + leftSet.difference(rightSet); const getSetIntersection = (leftSet: Set, rightSet: Set) => - leftSet.intersection?.(rightSet) || - new Set(Array.from(leftSet).filter(key => rightSet.has(key))); + leftSet.intersection(rightSet); export function diffKeys(oldList: T[], newList: T[]) { const oldSet = new Set(oldList), From c1000d164f73a18ec961211690d196bbe8c4d658 Mon Sep 17 00:00:00 2001 From: TechQuery Date: Wed, 1 Jul 2026 06:35:25 +0800 Subject: [PATCH 6/6] [optimize] simplify Copilot codes --- package.json | 2 +- source/data.ts | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 3ae4a99..2eb0370 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "web-utility", - "version": "4.7.0", + "version": "4.7.1", "license": "LGPL-3.0", "author": "shiy2008@gmail.com", "description": "Web front-end toolkit based on TypeScript", diff --git a/source/data.ts b/source/data.ts index 6036cdf..32ebad5 100644 --- a/source/data.ts +++ b/source/data.ts @@ -133,23 +133,14 @@ export enum DiffStatus { New = 1 } -const getSetDifference = (leftSet: Set, rightSet: Set) => - leftSet.difference(rightSet); - -const getSetIntersection = (leftSet: Set, rightSet: Set) => - leftSet.intersection(rightSet); - export function diffKeys(oldList: T[], newList: T[]) { const oldSet = new Set(oldList), newSet = new Set(newList); const map = {} as Record; - for (const item of getSetDifference(oldSet, newSet)) - map[item] = DiffStatus.Old; - for (const item of getSetIntersection(oldSet, newSet)) - map[item] = DiffStatus.Same; - for (const item of getSetDifference(newSet, oldSet)) - map[item] = DiffStatus.New; + for (const item of oldSet.difference(newSet)) map[item] = DiffStatus.Old; + for (const item of oldSet.intersection(newSet)) map[item] = DiffStatus.Same; + for (const item of newSet.difference(oldSet)) map[item] = DiffStatus.New; return { map,