JS代码片段-获取Array数组中的所有唯一值并删除重复项

在 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' } ]

声明:部分内容来自网络

Awesome Top - 跟踪开源热点,精选热门开源项目,分析开源项目趋势,挖掘开源项目价值!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农界的小蜜蜂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值