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

之 JS数组去重

开发技术 开发技术 2周前 (05-12) 23次浏览
理一遍去重,希望可以像离骚前两句话一样这辈子可以脱口而出。 --- 长太息以掩涕兮,哀民生之多艰 复制代码

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

如果第一次出现的索引值和元素索引值一样则,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.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跑一遍再看看。复制代码


程序员灯塔 , 版权所有
转载请注明原文链接:https://www.wangt.cc/2020/05/%e4%b9%8b-js%e6%95%b0%e7%bb%84%e5%8e%bb%e9%87%8d/
喜欢 (0)