JavaScript数组去重—ES6的两种方式
说明
JavaScript数组去重这个问题,经常出现在面试题中,以前也写过一篇数组去重的文章,(JavaScript 数组去重的多种方法原理详解)但感觉代码还是有点不够简单,今天和大家再说两种方法,代码可是足够的少了。
解释
方法一:
function unique(arr) {
const res = new Map();
return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
就这么短,就可以了,我们来解释一下为什么。
Map对象
Map是ES6 提供的新的数据结构。
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
下表列出了 Map 对象的方法。
Map对象还有一个size属性,他返回Map对象的键/值对的数量。
数组的 filter() 方法
filter() 方法创建一个新的数组,新数组中的元素 是 通过检查 指定数组 中 符合条件的所有元素。
语法:
array.filter(function(currentValue,index,arr), thisValue)
参数说明:
箭头函数
return arr.filter((a) => !res.has(a) && res.set(a, 1))
//上面的代码可以改成这样
return arr.filter(function(a){
return !res.has(a) && res.set(a, 1);
});
1、箭头函数写代码拥有更加简洁的语法;
2、不会绑定this。
了解更多,点这里
方法一 分析
function unique(arr) {
//定义常量 res,值为一个Map对象实例
const res = new Map();
//返回arr数组过滤后的结果,结果为一个数组
//过滤条件是,如果res中没有某个键,就设置这个键的值为1
return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
方法二:
function unique(arr) {
return Array.from(new Set(arr))
}
这个方法的代码量更少,简直不可思议。
数组的 from方法
Array.from() 方法从一个类似数组或可迭代的对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等) 中创建一个新的数组实例
语法:
Array.from(arrayLike[, mapFn[, thisArg]])
示例代码:
const bar = ["a", "b", "c"];
Array.from(bar);
// ["a", "b", "c"]
Array.from('foo');
// ["f", "o", "o"]
Set对象
Set 对象允许你存储任何类型的 唯一值 ,无论是原始值或者是对象引用。
Set对象是值的集合,你可以按照插入的顺序迭代它的元素。
Set中的元素只会出现一次,即 Set 中的元素是唯一的。
语法:
new Set([iterable]);
参数:
iterable,如果传递一个可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等),它的所有元素将被添加到新的 Set中。如果不指定此参数或其值为null,则新的 Set为空。
下表列出了 Set 对象的方法。
Set对象和Map对象一样,都有一个size属性,他返回Set对象的值的个数。
方法二 分析
function unique(arr) {
//通过Set对象,对数组去重,结果又返回一个Set对象
//通过from方法,将Set对象转为数组
return Array.from(new Set(arr))
}
总结
这次说的两个方法,真的很简单,主要就是靠ES6里的新东西,难度不大,代码简单,主要就是多用用就好了。
经人提醒,再补充一种,[...new Set(arr)]
不懂 ... 的朋友,可以看这里 js扩展运算符
参考
ES6新特性:Javascript中的Map和WeakMap对象
http://www.cnblogs.com/dilige...
Set和Map数据结构
http://es6.ruanyifeng.com/#do...
MDN
https://developer.mozilla.org...
Array filter()
http://www.runoob.com/jsref/j...
Array.from()
https://developer.mozilla.org...
JavaScript初学者必看“箭头函数”
http://www.cnblogs.com/fundeb...