Skip to content
VersionSize

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 TypeError if 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 Set internally for high performance.

See Also

  • filter: Create a subset of an array based on a predicate.
  • compact: Remove falsy values from an array.
  • aggregate: Group and aggregate array elements.