• 如果您觉得本站非常有看点，那么赶紧使用Ctrl+D 收藏吧

# 之 JS数组去重

5个月前 (05-12) 144次浏览
`理一遍去重，希望可以像离骚前两句话一样这辈子可以脱口而出。 --- 长太息以掩涕兮，哀民生之多艰 复制代码`

### 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 复制代码`

### 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 (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.025146484375ms 复制代码`

• `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.019775390625ms 复制代码`
• 可以对 `[]` 去重， `[] !== []` 返回 `true`
• []（object）== ![]（Boolean） 转成布尔类型，转成数字类型做比较
• `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跑一遍再看看。复制代码`