数组去重是一个js中在面试中经常被问到的问题,被问到是因为确实能够考察一些问题。如果不使用第三方的工具库,完全使用原生的方法实现,能够比较好的巩固基础知识。
双层循环
var array1 = [1, 1, '1', '1'];
function unique(array) {
// res用来存储结果
var res = [];
for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {
for (var j = 0, resLen = res.length; j < resLen; j++) {
if (array[i] === res[j]) {
break; // 是跳出内层循环 继续进行外层循环
}
}
// 如果array[i]是唯一的,那么执行完循环,j等于resLen
if (j === resLen) {
res.push(array[i])
}
}
return res;
}
console.log(JSON.stringify(unique(array1))); // [1, "1"]
通过这个函数深刻的理解了循环的机制。也就是 外层循环一次内部如果没有限制条件。会执行完整个循环。还记得当时刚开始学习打印乘法表的时候,使用的也是整个双层循环的思想。在这个方法中,我们使用循环嵌套,最外层循环 array,里面循环 res,如果 array[i] 的值跟 res[j] 的值相等,就跳出循环,如果都不等于,说明元素是唯一的,这时候 j 的值就会等于 res 的长度, 根据这个特点进行判断,将值添加进 res。
使用indexOf 简化内层的循环。
var array2 = [1, 1, '1'];
function unique(array) {
var res = [];
for (var i = 0, len = array.length; i < len; i++) {
var current = array[i];
if (res.indexOf(current) === -1) {
res.push(current)
}
}
return res;
}
console.log(unique(array2));
排序后去重
试想我们先将要去重的数组使用 sort 方法排序后,相同的值就会被排在一起,然后我们就可以只判断当前元素与上一个元素是否相同,相同就说明重复,不相同就添加进 res,让我们写个demo
如果我们对一个已经排好序的数组去重,这种方法效率肯定高于使用 indexOf。
var array3 = [1, 1, '1'];
function unique(array) {
var res = [];
// 先使用concat 返回一个数组,不改变原来的数组
var sortedArray = array.concat().sort();
var seen;
// 这种将 sortedArray 长度保存为 变量的方法是很好的。可以提高性能。
for (var i = 0, len = sortedArray.length; i < len; i++) {
// 如果是第一个元素或者相邻的元素不相同
if (!i || seen !== sortedArray[i]) {
res.push(sortedArray[i])
}
seen = sortedArray[i];
}
return res;
}
console.log(unique(array3));
使用ES5中的去重方法
数组的indexOf方法返回的是第一个匹配元素出现的位置这里的 '第一个出现' 遇到重复的元素 输出的是同样的位置。数组的filter 接收一个回调函数,这个回调函数里面的规则是可以自定义的。
var array4 = ['louis', 'leo', 'leo', 1, '1'];
function unique(array) {
var res = array.filter(function (item, index, array) {
// console.log(array.indexOf(item),index);
return array.indexOf(item) === index;
})
return res;
}
console.log(unique(array4));
排序去重的方法
这里还是使用先排序后去重的思路 如果元素是第一个直接返回true 如果不是第一个则和前一个元素进行比较,只要不相同则返回true 否则是返回false。
var array5 = ['louis','leo','leo', 1, '1'];
function unique(array) {
return array.concat().sort().filter(function(item, index, array){
return !index || item !== array[index - 1]
})
}
console.log(unique(array5));
ES6方法
随着 ES6 的到来,去重的方法又有了进展,比如我们可以使用 Set 和 Map 数据结构, 以 Set 为例,ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。是不是感觉就像是为去重而准备的?让我们来写一版:
var array6 = ['leo','leo','name','kerry', '1'];
function unique(array) {
return Array.from(new Set(array));
}
console.log(unique(array6)); // ["leo", "name", "kerry", "1"]
// 简化一下
function unique(array) {
return [...new Set(array)];
}
// 可以再简化一下
var unique = (a) => [...new Set(a)]