diff --git a/src/array.ts b/src/array.ts index 60db772e..e20fe250 100644 --- a/src/array.ts +++ b/src/array.ts @@ -289,17 +289,17 @@ export const cluster = (list: readonly T[], size: number = 2): T[][] => { * to convert each item in the list to a comparable identity * value */ -export const unique = ( +export const unique = ( array: readonly T[], toKey?: (item: T) => K ): T[] => { const valueMap = array.reduce((acc, item) => { - const key = toKey ? toKey(item) : (item as any as string | number | symbol) - if (acc[key]) return acc - acc[key] = item + const key = toKey ? toKey(item) : item + if (acc.get(key)) return acc + acc.set(key, item) return acc - }, {} as Record) - return Object.values(valueMap) + }, new Map()) + return Array.from(valueMap.values()); } /** diff --git a/src/tests/array.test.ts b/src/tests/array.test.ts index 92a177c2..aa7fdf2d 100644 --- a/src/tests/array.test.ts +++ b/src/tests/array.test.ts @@ -390,6 +390,27 @@ describe('array module', () => { assert.equal(c.id, 'c') assert.equal(c.word, 'yolo') }) + test('correctly handles non string, number or symbol values', () => { + const list = [ + null, + null, + true, + true, + "true", + false, + { id: 'a', word: 'hello' }, + { id: 'a', word: 'hello' }, + ] + const result = _.unique(list) + assert.deepEqual(result, [ + null, + true, + "true", + false, + { id: 'a', word: 'hello' }, + { id: 'a', word: 'hello' }, + ]) + }) }) describe('range function', () => {