数组去重应该是面试必答题了吧,那么数组去重有哪些方法呢?哪种方法的性能比较高呢?
我写了一个测试模板来验证,分别创建了两个长度为 10W 和 5W 的数组,然后通过 distinct() 方法合并两个数组,并去掉其中的重复项
方法一:Array.filter() + indexOf
使用 ES6 的Array.filter() 遍历数组,并结合 indexOf 来排除重复项
mounted() {
this.distinct_test('方法一:Array.filter() + indexOf');
},
methods:{
distinct_test(desc){
let arr1 = Array.from(new Array(100000), (x, index)=>{
return index
})
let arr2 = Array.from(new Array(50000), (x, index)=>{
return index+index
})
console.log(desc)
let start = new Date().getTime()
console.log('开始数组去重')
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
return arr.filter((item, index)=> { return arr.indexOf(item) === index })
}
console.log('去重后的长度', distinct(arr1, arr2).length)
let end = new Date().getTime()
console.log('耗时', end - start)
}
},
方法二:双层for循环
最容易理解的方法,外层循环遍历元素,内层循环检查是否重复
当有重复值的时候,可以使用 push(),也可以使用 splice()
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
for (let i=0, len=arr.length; i<len; i++) {
for (let j=i+1; j<len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
// splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
len--;
j--;
}
}
}
return arr
}
非常久!我一度怀疑程序出了问题...
方法三:for...of + includes()
双重for循环的升级版,外层用 for...of 语句替换 for 循环,把内层循环改为 includes()
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
let result = []
for (let i of arr) {
!result.includes(i) && result.push(i)
}
return result
}
方法四:Array.sort()
首先使用 sort() 将数组进行排序
然后比较相邻元素是否相等,从而排除重复项
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
arr = arr.sort()
let result = [arr[0]]
for (let i=1, len=arr.length; i<len; i++) {
arr[i] !== arr[i-1] && result.push(arr[i])
}
return result
}
方法五:for...of + Object
利用对象的属性不会重复这一特性,校验数组元素是否重复
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
let result = []
let obj = {}
for (let i of arr) {
if (!obj[i]) {
result.push(i)
obj[i] = 1
}
}
return result
}
哟呵!超快der~
方法六:new set()
ES6 新增了 Set 这一数据结构,类似于数组,但 Set 的成员具有唯一性
基于这一特性,就非常适合用来做数组去重了
function distinct(a, b) {
// 数组去重
return Array.from(new Set([...a, ...b]))
}
方法七:利用Map数据结构去重
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
let map = new Map();
let array = new Array(); // 数组用于返回结果
for (let i = 0; i < arr.length; i++) {
if(map .has(arr[i])) { // 如果有该key值
map .set(arr[i], true); }
else {
map .set(arr[i], false); // 如果没有该key值
array .push(arr[i]);
}
}
return array ;
}
方法八:reduce+includes
function distinct(a, b) {
// 数组去重
let arr = a.concat(b);
return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
这么一比较,结果应该很明显了吧