From 0faafc1b5228f1893d80c44dbea7c01e0049dbb2 Mon Sep 17 00:00:00 2001 From: robonen Date: Thu, 24 Oct 2024 07:27:37 +0700 Subject: [PATCH] feat(packages/stdlib): add unique arrays util --- .../stdlib/src/arrays/unique/index.test.ts | 39 +++++++++++++++++++ packages/stdlib/src/arrays/unique/index.ts | 33 ++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 packages/stdlib/src/arrays/unique/index.test.ts create mode 100644 packages/stdlib/src/arrays/unique/index.ts diff --git a/packages/stdlib/src/arrays/unique/index.test.ts b/packages/stdlib/src/arrays/unique/index.test.ts new file mode 100644 index 0000000..4efcf04 --- /dev/null +++ b/packages/stdlib/src/arrays/unique/index.test.ts @@ -0,0 +1,39 @@ +import { describe, it, expect } from 'vitest'; +import { unique } from '.'; + +describe('unique', () => { + it('return an array with unique numbers', () => { + const result = unique([1, 2, 3, 3, 4, 5, 5, 6]); + expect(result).toEqual([1, 2, 3, 4, 5, 6]); + }); + + it('return an array with unique objects based on id', () => { + const result = unique( + [{ id: 1 }, { id: 2 }, { id: 1 }], + (item) => item.id, + ); + expect(result).toEqual([{ id: 1 }, { id: 2 }]); + }); + + it('return the same array if all elements are unique', () => { + const result = unique([1, 2, 3, 4, 5]); + expect(result).toEqual([1, 2, 3, 4, 5]); + }); + + it('handle arrays with different types of values', () => { + const result = unique([1, '1', 2, '2', 2, 3, '3']); + expect(result).toEqual([1, '1', 2, '2', 3, '3']); + }); + + it('handle arrays with symbols', () => { + const sym1 = Symbol('a'); + const sym2 = Symbol('b'); + const result = unique([sym1, sym2, sym1]); + expect(result).toEqual([sym1, sym2]); + }); + + it('return an empty array when given an empty array', () => { + const result = unique([]); + expect(result).toEqual([]); + }); +}); \ No newline at end of file diff --git a/packages/stdlib/src/arrays/unique/index.ts b/packages/stdlib/src/arrays/unique/index.ts new file mode 100644 index 0000000..6175c1d --- /dev/null +++ b/packages/stdlib/src/arrays/unique/index.ts @@ -0,0 +1,33 @@ +export type UniqueKey = string | number | symbol; +export type Extractor = (value: Value) => Key; + +/** + * @name unique + * @category Arrays + * @description Returns a new array with unique values from the original array + * + * @param {Value[]} array - The array to filter + * @param {Function} [extractor] - The function to extract the value to compare + * @returns {Value[]} - The new array with unique values + * + * @example + * unique([1, 2, 3, 3, 4, 5, 5, 6]) //=> [1, 2, 3, 4, 5, 6] + * + * @example + * unique([{ id: 1 }, { id: 2 }, { id: 1 }], (a, b) => a.id === b.id) //=> [{ id: 1 }, { id: 2 }] + * + * @since 0.0.3 + */ +export function unique( + array: Value[], + extractor?: Extractor, +) { + const values = new Map(); + + for (const value of array) { + const key = extractor ? extractor(value) : value as any; + values.set(key, value); + } + + return Array.from(values.values()); +}