在 JavaScript 中,要从Array数组中删除重复项可以通过多种方式完成,例如使用Array.prototype.reduce(),Array.prototype.filter()甚至是简单的for
循环。但有一种更简单的方法可以做到这一点,即使用内置Set对象。
1.获取数组中所有唯一值
Set 不能包含重复的值,并且可以很容易地从数组的值初始化。然后,由于它本身是可迭代的,我们可以使用扩展运算符(...)将其中的项展开,再转成数组。
const uniqueElements = arr => [...new Set(arr)];
uniqueElements([1, 2, 2, 3, 4, 4, 5]); // [1, 2, 3, 4, 5]
2.检查数组是否包含重复值
Set 没有属性 length,但有size
属性。我们可以用它来检查数组是否包含重复值。
const hasDuplicates = arr => arr.length !== new Set(arr).size;
hasDuplicates([1, 2, 2, 3, 4, 4, 5]); // true
hasDuplicates([1, 2, 3, 4, 5]); // false
3.删除数组中的重复值
如果我们只想保留非重复的值,我们可以使用Array.prototype.filter()方法。出现多次的元素必然有两个不同的索引,因此我们可以使用Array.prototype.indexOf()和Array.prototype.lastIndexOf()来检。如果数组中有许多重复的值,可以将其先转换为Set来提高性能。
const removeNonUnique = arr =>
[...new Set(arr)].filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
removeNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 3, 5]
类似地,我们移除所有只出现一次的值。在这种情况下,两个索引必须是相同的。
const removeUnique = arr =>
[...new Set(arr)].filter(i => arr.indexOf(i) !== arr.lastIndexOf(i));
removeUnique([1, 2, 2, 3, 4, 4, 5]); // [2, 4]
4.重用函数查找重复项
更复杂的数据,如对象,无法使用相等比较进行比较,因此我们需要使用函数来检查重复项。Set对象在这里用处不大,因此我们可以使用Array.prototype.reduce()和Array.prototype.some()手动填充一个只包含唯一值的新数组。通过使用数组方法,我们还可以检查数组中是否包含重复项,或者删除其中的重复项。
const uniqueElementsBy = (arr, fn) =>
arr.reduce((acc, v) => {
if (!acc.some(x => fn(v, x))) acc.push(v);
return acc;
}, []);
const hasDuplicatesBy = (arr, fn) =>
arr.length !== new Set(arr.map(fn)).size;
const removeNonUniqueBy = (arr, fn) =>
arr.filter((v, i) => arr.every((x, j) => (i === j) === fn(v, x, i, j)));
const data = [
{ id: 0, value: 'a' },
{ id: 1, value: 'b' },
{ id: 2, value: 'c' },
{ id: 1, value: 'd' },
{ id: 0, value: 'e' }
];
const idComparator = (a, b) => a.id == b.id;
const idMap = a => a.id;
uniqueElementsBy(data, idComparator);
// [ { id: 0, value: 'a' }, { id: 1, value: 'b' }, { id: 2, value: 'c' } ]
hasDuplicatesBy(data, idMap); // true
removeNonUniqueBy(data, idComparator); // [ { id: 2, value: 'c' } ]
声明:部分内容来自网络