|
- /**
- * Return an array equal to the given one, but with duplicate items removed.
- * @param items The array to deduplicate. Not mutated.
- * @param getItemId Get the identifier to compare sameness of two items.
- * Defaults to the item itself, so sameness means strict equality
- * (`item1 === item2`).
- * @param merge Callback function to merge duplicate items if desired; the
- * returned value will take the place of the first item.
- * @returns A new array.
- */
- export function unique<T>(
- items: T[],
- getItemId: (item: T) => any = (item) => item,
- merge?: (item1: T, item2: T) => T,
- ): T[] {
- const seen = new Set();
- const newItems: T[] = [];
- for (const item of items) {
- const id = getItemId(item);
- if (id === undefined || !seen.has(id)) {
- newItems.push(item);
- seen.add(id);
- } else if (merge) {
- const indexOfConflictingItem = newItems.findIndex(
- (newItem) => getItemId(newItem) === id,
- );
- newItems[indexOfConflictingItem] = merge(
- newItems[indexOfConflictingItem],
- item,
- );
- }
- }
- return newItems;
- }
|