深入 JS 之数组去重
兼容方式
var arr = [1, 1, '1', '1']; function unique(arr) { var res = []; for (var i = 0; i < arr.length; i++) { for (var j = 0; j < res.length; j++) { if (arr[i] === res[j]) break; } if (j === res.length) { // 遍历完都无重复则会相等 res.push(arr[i]); } } return res } console.log(unique(arr));
indexOf
var arr = [1, 1, '1', '1', 2, 3, 4, 4, 3]; function unique(arr) { var res = []; for (var i = 0; i < arr.length; i++) { if(res.indexOf(arr[i]) === -1) { res.push(arr[i]); } } return res; } console.log(unique(arr));
排序后再去重
var arr = [1, 1, '1', '1', 2, 3, 4, 4, 3]; function unique(arr) { var res = []; var sortArr = arr.concat().sort(); // 浅拷贝一个新数组来sort排序 var seen; // console.log(sortArr); // [ 1, 1, '1', '1', 2, 3, 3, 4, 4 ] for (var i=0; i<sortArr.length; i++) { if(!i || seen !== sortArr[i]) { // 不是第一个元素或者不等于上一个元素 res.push(sortArr[i]); } seen = sortArr[i]; } return res; } console.log(unique(arr));
对一个已经排好序的数组去重,这种方法效率肯定高于使用 indexOf
结合 indexOf 和排序去重封装一个工具函数
知道了这两种方法后,我们可以去尝试写一个名为 unique 的工具函数,我们根据一个参数 isSorted 判断传入的数组是否是已排序的,如果为 true,我们就判断相邻元素是否相同,如果为 false,我们就使用 indexOf 进行判断
var array1 = [1, 2, '1', 2, 1]; var array2 = [1, 1, '1', 2, 2]; // 第一版 function unique(array, isSorted) { var res = []; var seen = []; for (var i = 0, len = array.length; i < len; i++) { var value = array[i]; if (isSorted) { if (!i || seen !== value) { res.push(value) } seen = value; } else if (res.indexOf(value) === -1) { res.push(value); } } return res; } console.log(unique(array1)); // [1, 2, "1"] console.log(unique(array2, true)); // [1, "1", 2]
Array.prototype.filter 简化去重
简化 indexOf
var arr = [1, 1, '1', '1', 2, 3, 4, 4, 3]; function unique(arr) { var res = arr.filter(function (item, index, array) { return array.indexOf(item) === index; // indexOf只返回该值在数组中的顺序第一次出现的索引 }) return res; } console.log(unique(arr));
简化排序
function sortUnique(arr) { var res = arr.concat().sort().filter(function(item, index, array) { return !index || item !== array[index - 1]; }) return res; } console.log(sortUnique(arr));
ES6 的方法
如 Set 和 Map 这两个数据结构,以 Set 为例,类似数组,并且保证值不重复,似乎天生就为数组去重而生。
采用 Set 的话有很多种写法:
// Set数据结构 var arr = [1, 1, '1', '1', 2, 3, 4, 4, 3]; function unique(arr) { // 第一种形式 // var value = new Set(arr); // return Array.from(value); // return Array.from(new Set(arr)); // 第二种形式 return [...new Set(arr)]; } // 再简化第三种形式 var unique1 = (arr) => [...new Set(arr)]; console.log(unique1(arr));
采用Map:
var arr = [1, 1, '1', '1', 2, 3, 4, 4, 3]; function unique(arr) { var value = new Map(); return arr.filter((item) => !value.has(item) && value.set(item, 1)); } console.log(unique(arr));
特殊类型比较
去重的方法就到此结束了,然而要去重的元素类型可能是多种多样,除了例子中简单的 1 和 '1' 之外,其实还有 null、undefined、NaN、对象等,那么对于这些元素,之前的这些方法的去重结果又是怎样呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论