Created
July 25, 2025 07:26
-
-
Save JTBrinkmann/2145575e3cb12a9679203159c184f959 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type CompareResult<T> = { | |
common: T[] | |
added: T[] | |
removed: T[] | |
} | |
export const compareSortedArrays = <T,>(oldArray: T[], newArray: T[], getKey?: (item: T) => any): CompareResult<T> => { | |
const common: T[] = [] | |
const added: T[] = [] | |
const removed: T[] = [] | |
let i = 0 // Pointer for oldArray | |
let j = 0 // Pointer for newArray | |
while (i < oldArray.length && j < newArray.length) { | |
const oldKey = getKey ? getKey(oldArray[i]) : oldArray[i] | |
const newKey = getKey ? getKey(newArray[j]) : newArray[j] | |
if (oldKey === newKey) { | |
// item is in both arrays | |
common.push(oldArray[i]) | |
i++ | |
j++ | |
} else if (oldKey < newKey) { | |
// item is in oldArray but not in newArray (removed) | |
removed.push(oldArray[i]) | |
i++ | |
} else { | |
// item is in newArray but not in oldArray (added) | |
// note: also applies for loose equality, e.g. 1 == "1" | |
added.push(newArray[j]) | |
j++ | |
} | |
} | |
// add remaining items from oldArray (removed) | |
while (i < oldArray.length) { | |
removed.push(oldArray[i]) | |
i++ | |
} | |
// add remaining items from newArray (added) | |
while (j < newArray.length) { | |
added.push(newArray[j]) | |
j++ | |
} | |
return { common, added, removed } | |
} | |
// example usage | |
compareSortedArrays( | |
[{ id: 1 }, { id: 2 }, { id: 3 }], | |
[{ id: 2 }, { id: 3 }, { id: 4 }], | |
(item) => item.id, // alternatively: JSON.stringify | |
) | |
// { | |
// added: [ { id: 4 } ], | |
// common: [ { id: 2 }, { id: 3 } ], | |
// removed: [ { id: 1 } ] | |
// } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment