If you don't use a library like lodash or radash for example. You can use Set as answered by @Vic.
Just a bug detected is about objects without same keys order. For example
{a: '1', b: '2'} and {b: '2', a: '1'} are not string equals.
Here is a working solution with covered cases
Implementation
uniq(source) {
if (!Array.isArray(source)) {
return [];
}
return [...new Set(source.map(o => {
const sortedObjectKeys = Object.keys(o).sort();
const obj = Object.assign({}, ...sortedObjectKeys.map(k => ({[k]: o[k]})) as any);
return JSON.stringify(obj);
}))]
.map(s => JSON.parse(s));
}
Test cases
describe(`uniq`, () => {
it('should return unique collection values', () => {
expect(uniq([{v: 1}, {v: 2}, {v: 1}])).toEqual([{v: 1}, {v: 2}]);
});
it('should return unique collection values for unsorted properties', () => {
expect(uniq([{a: 'test', v: 1}, {v: 2}, {v: 1, a: 'test'}])).toEqual([{a: 'test', v: 1}, {v: 2}]);
});
it('should return empty array for non array source', () => {
expect(uniq({v: 1})).toEqual([]);
expect(uniq('aString')).toEqual([]);
expect(uniq(125)).toEqual([]);
expect(uniq(true)).toEqual([]);
expect(uniq([])).toEqual([]);
expect(uniq(undefined)).toEqual([]);
expect(uniq(null)).toEqual([]);
});
});