const array = ['?', 1, 2, 3, '?','?', 3];
// 第一种方法 "Set"
[...new Set(array)]
// 第二种方法 “Filter”
array.filter((item, index) => array.indexOf(item) === index);
// 第三种方法 "Reduce"
array.reduce((unique, item) => unique.includes(item) ? unique : [...unique, item], []);
// 输入:
// ["?", 1, 2, 3]
Set
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
const array = ['?',1,2,'?','?',3];
// 第一步
const uniqueSet = new Set(array);
// Set {"?", 1, 2, 3}
// 第二步
const backToArray = [...uniqueSet];
// ["?", 1, 2, 3]
也可以使用 Array.from
将一个集合转换成数组:
const array = ['?',1,2,'?','?',3];
Array.from(new Set(array));
// ["?", 1, 2, 3]
filter
为了理解这种实现方式,我们先来看下这两个方法的作用:indexOf
和 filter
indexOf
方法可返回给定元素在数组中首次出现的位置
const array = ['?',1,2,'?','?',3];
array.indexOf('?'); // 0
array.indexOf(1); // 1
array.indexOf(2); // 2
array.indexOf(3); // 5
filter()
方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
我们通过判断元素当前索引与数组元素首次出现的位置是否相同,来作为筛选条件
让我们来看看循环数组时发生了什么
const array = ['?',1,2,'?','?',3];
array.filter((item, index) => {
console.log(
// 输出元素 item
item,
// 输出 index
index,
// 输出 indexOf
array.indexOf(item),
// 输出过滤条件
array.indexOf(item) === index,
);
return array.indexOf(item) === index
});
下面是console.log的输出。index 与 indexOf 不匹配的称为重复项。不包含在过滤后的数组中。
同样,我们可以使用 filter()
方法从数组中找出重复的值
const array = ['?',1,2,'?','?',3];
array.filter({item, index} => array.indexOf(item) !== index);
// ['?','?']
reduce
reduce()
方法对数组中的每个元素执行一个由我们提供的reducer函数(升序执行),将其结果汇总为一个值。
在本例子中,我们的reducer函数是去检查我们的最终数组是否包含当前元素。
如果没有,则添加到最终数组中。否则,跳过该数组并返回原最终数组。
reduce
有点难理解,让我们通过查看每一步的输出去更好的理解:
const array = ['?',1,2,'?','?',3];
array.reduce((unique, item) => {
console.log(
// 输出item
item,
// 输出最终数组
unique,
// 输出判断条件(当输出 `false` ,把该元素push到最终数组)
unique.includes(item),
// 输出函数reducer函数结果
unique.includes(item) ? unique : [...unique, item],
);
return unique.includes(item) ? unique : [...unique, item]
}, []); // 累加器的初始值是个空数组
// 最终输出:
// ["?", 1, 2, 3]