uniq
The uniq utility creates a new array containing only unique values from the input array. It removes duplicates, preserving the first occurrence of each unique value.
Implementation
View Source Code
ts
import { assert } from '../function/assert';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';
import type { Primitive, Selector } from '../types';
/**
* Creates a new array with duplicate values removed.
*
* @example
* ```ts
* uniq([1, 2, 2, 3, 3, 3]); // [1, 2, 3]
* const arrObj = [{ id: 1 }, { id: 2 }, { id: 2 }, { id: 3 }, { id: 3 }, { id: 3 }];
* uniq(arrObj, 'id'); // [{ id: 1 }, { id: 2 }, { id: 3 }]
* uniq(arrObj, item => item.id); // [{ id: 1 }, { id: 2 }, { id: 3 }]
* ```
*
* @param array - The array to process.
* @param [selector] - The key(s) to compare objects or a function to generate comparison values.
* @returns A new duplicate-free array.
* @throws {TypeError} - If the input is not an array or if the key is invalid.
*/
export function uniq<T>(array: T[], selector?: Selector<T>): T[] {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { type: TypeError });
if (array.length <= 1) {
return [...array];
}
if (!selector) {
return [...new Set(array)];
}
const seen = new Map<Primitive, T>();
const getKey = typeof selector === 'function' ? selector : (item: T) => item[selector];
return array.filter((item) => {
const key = getKey(item) as Primitive;
if (seen.has(key)) {
return false;
}
seen.set(key, item);
return true;
});
}
uniq.fp = true;Features
- Isomorphic: Works in both Browser and Node.js.
- Deep Comparison: Use a selector to deduplicate based on specific properties.
- Immutable: Returns a new array, leaving the original array unchanged.
API
Type Definitions
ts
export type Selector<T> = keyof T | ((item: T) => Primitive);ts
function uniq<T>(array: T[], selector?: Selector<T>): T[];Parameters
array: The array to process.selector: Optional. A property key or a function that returns the value used for comparison (defaults to direct element equality).
Returns
- A new array containing only unique elements.
Examples
Basic Deduplication
ts
import { uniq } from '@vielzeug/toolkit';
const numbers = [1, 2, 2, 3, 3, 3];
uniq(numbers); // [1, 2, 3]Deduplicating Objects by Property
ts
import { uniq } from '@vielzeug/toolkit';
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 2, name: 'Robert' }, // Duplicate ID
{ id: 3, name: 'Charlie' },
];
// Deduplicate by 'id' key
const uniqueById = uniq(users, 'id');
// [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]Deduplicating with a Selector Function
ts
import { uniq } from '@vielzeug/toolkit';
const data = ['apple', 'Apple', 'banana', 'BANANA'];
// Deduplicate ignoring case
const uniqueCaseInsensitive = uniq(data, (s) => s.toLowerCase());
// ['apple', 'banana']Implementation Notes
- Throws
TypeErrorif the input is not an array. - For objects, the first encountered element for a given key is preserved.
- When no selector is provided, it uses a
Setinternally for high performance.