理一遍去重,希望可以像离骚前两句话一样这辈子可以脱口而出。
--- 长太息以掩涕兮,哀民生之多艰
1、ES6 new Set去重
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function unique(arr) {
return Array.from(new Set(arr))
}
console.log(unique(list))
// [4, "lalala", true, undefined, "true", null, 0, {}, {}, [], [], NaN]
// 0.0029296875ms
简化一下
[...new Set(list)]
- Array.from 将
类似数组的对象和可遍历的对象转化为真正的数组 - Set ES6 新的数据结构,set对象是值的
集合,不会储存重复的元素 - 无法对
{}和[]去重
2、嵌套循环去重(原始)
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni (arrList) {
// reasonList 用来储存去重后的数组
let reasonList = []
for(var i = 0; i < arrList.length; i++) {
for (var j = 0; j < reasonList.length; j++) {
// 当找到两个数组中有相同的就停止循环
if (arrList[i] === reasonList[j]) {
break
}
}
// 如果没有相同的,执行完循环j === reasonList.length
if (j === reasonList.length) {
reasonList.push(arrList[i])
}
}
return reasonList
}
console.log(uni(list))
//[4, "lalala", true, undefined, "true", null, 0, {}, {}, [], [], NaN, NaN]
//0.025146484375ms
嵌套循环,原始数组arrList和一个新的reasonList,判断arrList[i]和reasonList[j]是否相等,如果不相等,就说明元素是唯一的,循环执行完j的长度等于reasonList[j]的长度,把唯一的元素push到新的数组里。
3、indexof去重(嵌套循环的简化)
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni (arrList) {
let reasonList = []
for(var i = 0; i < arrList.length; i++) {
//
if (reasonList.indexOf(arrList[i]) === -1 )
{
reasonList.push(arrList[i])
}
}
return reasonList
}
console.log(uni(list))
//[4, "lalala", true, undefined, "true", null, 0, {}, {}, [], [], NaN, NaN]
//0.026123046875ms
4、indexOf去重(判断indexOf的值是否与元素索引值相等)
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni (arrList) {
let reasonList = []
for(var i = 0; i < arrList.length; i++) {
if (arrList.indexOf(arrList[i]) === i )
{
reasonList.push(arrList[i])
}
}
return reasonList
}
console.log(uni(list))
//[4, "lalala", true, undefined, "true", null, 0, {}, {}, [], []]
//0.025146484375ms
var removeDuplicates = function(nums) {
for(let i = 0; i < nums.length; i++) {
if (nums.indexOf(nums[i]) !== i) {
nums.splice(i, 1)
i--
}
}
return nums.length
};
如果第一次出现的索引值和元素索引值一样则,push到新的数组
indexOf返回调用它的String/Array对象中第一次出现的指定值的索引
5、排序去重(先排序,比较当前元素和前一个元素是否相同)
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni (arrList) {
let reasonList = []
arrList.sort()
for(var i = 0; i < arrList.length; i++) {
if(arrList[i+1] !== arrList[i]) {
reasonList.push(arrList[i+1])
}
}
return reasonList
}
console.log(uni(list))
//[], 0, 4, NaN, NaN, {}, {}, "lalala", null, true, "true", undefined]
//0.039775390625ms
- 可以对
[]去重,[] !== []返回true。 - [](object)==  转成布尔类型,转成数字类型做比较
sort()用原地算法对数组的元素进行排序
6、排序去重(头尾比较去重,和5实际上一样,多定了一个变量)
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni (arr) {
var res = [],
end;
arr.sort()
end = arr[0]
res.push(arr[0])
for(var i=1; i < arr.length; i++){
// 这里需要用!==
// [] == 0 返回true
if(arr[i] !== end) {
res.push(arr[i])
end=arr[i]
}
}
return res
}
//[[], [], 0, 4, NaN, NaN, {…}, {…}, "lalala", null, true, "true", undefined]
//0.02392578125ms
7、 filter去重
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni(arr){
var reasultList = arr.filter(function(item,index,arr){
return arr.indexOf(item) === index
})
return reasultList
}
//[4, "lalala", true, undefined, "true", null, 0, {…}, {…}, Array(0), Array(0)]
// 0.031005859375ms
NaN直接去掉了
8、reduce去重
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni(arr){
return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
//[4, "lalala", true, undefined, "true", null, 0, {…}, {…}, Array(0), Array(0), NaN]
//0.003173828125ms
- 可以对
NaN去重
9、利用对象属性不会重复去重(for...of + Object )
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni(arr) {
var res = []
let obj = {}
for (let i of arr) {
if (!obj[i]) {
res.push(i)
obj[i] = 1
}
}
return res
}
// [4, "lalala", true, undefined, null, 0, {}, [], NaN]
// 0.03369140625ms
- 这个方法可以对
[]、{}、NaN去重,但是true会直接去掉,慎用 - 有人说这个比set快可能数据量不到 看不到效果
10、for...of + includes
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni(arr) {
var res = []
for (let i of arr) {
!res.includes(i) && res.push(i)
}
return res
}
uni(list)
// [4, "lalala", true, undefined, "true", null, 0, {}, {}, [], [], NaN]
// 0.02197265625ms
- 可以对NaN去重
11、map去重
var list = [4, 4, "lalala", "lalala", true, true, undefined, 'true', 'true', undefined, undefined, null, null, 0, 0, {}, {}, [], [], NaN, NaN]
function uni(arr) {
let map = new Map()
let array = new Array()
for (let i = 0; i < arr.length; i++){
if(map.has(arr[i])) {
map.set(arr[i], true)
} else {
map.set(arr[i], false)
array.push(arr[i])
}
}
return array
}
console.log(uni(list))
//[4, "lalala", true, undefined, "true", null, 0, {}, {}, [], [], NaN]
//0.033203125ms
小结
Set是比较快的,但是reduce的方式看上去和set时间差不多
由于是用浏览器运行的而且数据少,有空用node跑一遍再看看。