原文:How to Remove Array Duplicates in ES6
翻译:Hytonight云息
有三种方法可以过滤掉一个数组的重复元素并且返回去重后的新数组。我最喜欢使用Set
,因为它最精简。
const array = [' ', 1, 2, ' ',' ', 3];
// 1: "Set"
[...new Set(array)];
// 2: "Filter"
array.filter((item, index) => array.indexOf(item) === index);
// 3: "Reduce"
array.reduce((unique, item) =>
unique.includes(item) ? unique : [...unique, item], []);
// RESULT:
// [' ', 1, 2, 3];
1. 使用 Set
set
是ES6中引入的新的数据类型。set
只允许存储不重复的值,所以当你放入一个数组,它会自动去掉重复的值。
OK,我们回去将代码分解开来看,其实就做了两件事情:
- 首先,我们通过原数组
array
创建了一个新的set
,所有的重复值都被去除了。 - 然后,我们通过展开运算符
…
转换回了数组
const array = [' ', 1, 2, ' ',' ', 3];
// Step 1
const uniqueSet = new Set(array);
// Set { ' ', 1, 2, 3 }
// Step 2
const backToArray = [...uniqueSet];
// [' ', 1, 2, 3]
当然,你也可以使用Array.form
来将set
转回数组
const array = [' ', 1, 2, ' ',' ', 3];
Array.from(new Set(array));
// [' ', 1, 2, 3]
2.使用 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
filter()
方法通过给定的条件(一个函数)来返回一个新的数组。换句话说,如果轮到的这个元素进入了条件函数后结果为true
,那么它将被加入到过滤后的新数组中,反之则不会加入到结果数组中。
const array = [' ', 1, 2, ' ',' ', 3]
array.filter((item, index) => {
console.log(
// a. Item
item,
// b. Index
index,
// c. indexOf
array.indexOf(item),
// d. Condition
array.indexOf(item) === index,
);
return array.indexOf(item) === index
});
下面就是执行上述代码后console
的输出。可以看到,重复的元素就是那些index
和indexOf
不同的元素。所以,重复元素返回的结果就是false
。
(译者按:说的再简单点,就是所有重复元素只取第一次出现的那个,后来出现的丢弃)
那如何得到重复的元素呢?
也是使用filter()
,只要将上面的条件反一反就可以啦,如下:
const array = [' ', 1, 2, ' ',' ', 3];
array.filter((item, index) => array.indexOf(item) !== index);
// [' ',' ']
3. 使用 reduce()
reduce()
方法通过提供的reducer
函数来reduce
数组中的元素并且将他们合并为一个新的数组。
(译者按:难翻,看MDN解释——reduce()
方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值)
在这个例子中,我们的reducer
函数用来检查最终结果是否已经包含这个item
。如果不包含,那么将它放入最终结果,如果已经包含,则丢弃(或者说跳过)这个item
。
reduce
常常会难以理解,所以我们一步步来看。
const array = [' ', 1, 2, ' ',' ', 3];
array.reduce((unique, item) => {
console.log(
// a. Item
item,
// b. Final Array (Accumulator)
unique,
// c. Condition (Remember it only get pushed if this returns `false`)
unique.includes(item),
// d. Reducer Function Result
unique.includes(item) ? unique : [...unique, item],
);
return unique.includes(item) ? unique : [...unique, item]
}, []); // The initial value of our Accumulator is an empty array
// RESULT:
// [' ', 1, 2, 3];
console
输出如下: