https://juejin.im/post/5b0284ac51882542ad774c45
双重循环、Array.prototype.indexOf()、Array.prototype.sort()、Array.prototype.reduce()、Map、Set
双重循环
双重循环去重实现比较容易。
实现一:
Array.prototype.unique = function () {
const newArray = [];
let isRepeat;
for (let i = 0; i < this.length; i++) {
isRepeat = false;
for (let j = 0; j < newArray.length; j++) { if (this[i] === newArray[j]) { isRepeat = true; break; }
}
if (!isRepeat) { newArray.push(this[i]); }
}
return newArray;
}
Array.prototype.indexOf()
基本思路:如果索引不是第一个索引,说明是重复值。
实现一:
利用Array.prototype.filter()过滤功能,Array.prototype.indexOf()返回的是第一个索引值,只将数组中元素第一次出现的返回,之后出现的将被过滤掉
Array.prototype.unique = function () {
return this.filter((item, index) => { return this.indexOf(item) === index; })//实现一
this.forEach(item => { if (newArray.indexOf(item) === -1) { newArray.push(item); } });
return newArray;实现二:
}
Array.prototype.sort()
基本思路:先对原数组进行排序,然后再进行元素比较。
实现一:
Array.prototype.unique = function () {
const newArray = [];
this.sort();
for (let i = 0; i < this.length; i++) { if (this[i] !== this[i + 1]) { newArray.push(this[i]); } }//实现一
for (let i = 0; i < this.length; i++) { if (this[i] !== newArray[newArray.length - 1]) { newArray.push(this[i])} }
return newArray;
}
Array.prototype.includes()
Array.prototype.unique = function () {
const newArray = [];
this.forEach(item => { if (!newArray.includes(item)) { newArray.push(item); } });
return newArray;
}
Array.prototype.reduce()
Array.prototype.unique = function () {
return this.sort().reduce((init, current) => {
if(init.length === 0 || init[init.length - 1] !== current){ init.push(current); }
return init;
}, []);
}
Map
实现一:
Array.prototype.unique = function () {
const newArray = [];
const tmp = new Map();
for(let i = 0; i < this.length; i++){ if(!tmp.get(this[i])){ tmp.set(this[i], 1); newArray.push(this[i]); }}
return newArray;
}
Array.prototype.unique = function () {
const tmp = new Map();
return this.filter(item => { return !tmp.has(item) && tmp.set(item, 1); })
}
Set
Array.prototype.unique =function(){constset =newSet(this);returnArray.from(set);}
Array.prototype.unique =function(){return[...newSet(this)];}
总结
除了考虑时间复杂度外、性能之外,还要考虑数组元素的数据类型(例如下面的例子)等问题权衡选择出采用哪种算法,例如:
const arr = [1, 1, '1', '1', 0, 0, '0', '0', undefined, undefined, null, null, NaN, NaN, {}, {}, [], [], /a/, /a/];
经过综合考虑,最优的数组去重算法是采用Map数据结构实现的算法。