mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 10:54:44 +00:00
feat(packages/stdlib): add unique arrays util
This commit is contained in:
39
packages/stdlib/src/arrays/unique/index.test.ts
Normal file
39
packages/stdlib/src/arrays/unique/index.test.ts
Normal file
@@ -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([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
33
packages/stdlib/src/arrays/unique/index.ts
Normal file
33
packages/stdlib/src/arrays/unique/index.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
export type UniqueKey = string | number | symbol;
|
||||||
|
export type Extractor<Value, Key extends UniqueKey> = (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<Value, Key extends UniqueKey>(
|
||||||
|
array: Value[],
|
||||||
|
extractor?: Extractor<Value, Key>,
|
||||||
|
) {
|
||||||
|
const values = new Map<Key, Value>();
|
||||||
|
|
||||||
|
for (const value of array) {
|
||||||
|
const key = extractor ? extractor(value) : value as any;
|
||||||
|
values.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(values.values());
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user