JS数组去重详细
发布时间:2021-11-07 14:51:42 所属栏目:教程 来源:互联网
导读:目录 1 测试用例2 JS 数组去重4大类型2.1 元素比较型2.1.1 双层 for 循环逐一比较(es5常用)2.1.2 排序相邻比较2.2 查找元素位置型2.2.1 indexOf2.2.2 findIndex2.3 元素是否存在型2.3.1 includes2.3.2 some2.4 依托数据结构特性2.4.1 Map2.4.2 Set(ES6 最
目录 1 测试用例2 JS 数组去重4大类型2.1 元素比较型2.1.1 双层 for 循环逐一比较(es5常用)2.1.2 排序相邻比较2.2 查找元素位置型2.2.1 indexOf2.2.2 findIndex2.3 元素是否存在型2.3.1 includes2.3.2 some2.4 依托数据结构特性2.4.1 Map2.4.2 Set(ES6 最常用)3 补充 1 测试用例 // 测试用例 const a = {}; const b = { c: 1 }; const array = [ 1, 1, "1", "1", {}, {}, { c: 1 }, { c: 1}, a, a, b, b, [], [], [1], [1], undefined, undefined, null, null, NaN, NaN, ]; 2 JS 数组去重4大类型 2.1 元素比较型 此类型通过数组元素之间进行比较来去重 2.1.1 双层 for 循环逐一比较(es5常用) 使用双层for循环逐一比较数组元素,用splice方法去除重复的元素 // 双层for循环 function uniq1(arr) { for (let i = 0; i < arr.length; i++) { for (let j = i + 1; j < arr.length; j++) { if (arr[i] === arr[j]) { arr.splice(j, 1) j-- } } } return arr } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN,NaN] 通过对比去重前后结果,重复的NaN没有去掉,因为NaN === NaN为false 2.1.2 排序相邻比较 使用sort()方法对数组元素进行排序,然后比较相邻元素,用splice方法去除重复的元素。 function uni2(arr) { arr.sort(); for (let i = 0; i < arr.length - 1; i++) { arr[i] === arr[i + 1] && arr.splice(i + 1, 1) && i--; } return arr; } 也可以创建新数组,将不重复的元素放入新数组中 function uniq3(arr) { arr = arr.sort() const newArr = [arr[0]] for (let i = 1; i < arr.length; i++) { if (arr[i] !== arr[i - 1]) { newArr.push(arr[i]) } } return newArr } // 去重结果 // [[],[],1,'1',[1],[1],NaN,NaN,{},{},{c:1},{c:1},{},{c:1},null,undefined] 重复的NaN没有去掉,因为NaN === NaN为false sort默认排序顺序是将元素转换为字符串,对象转换为字符串都是[object Object] ,所以sort方法不能对数组中的对象进行排序,也就有可能无法去除重复的对象,除非重复的对象本就相邻 2.2 查找元素位置型 此类型通过查找元素第一次出现的位置来去重 2.2.1 indexOf 通过indexOf查找当前元素第一次出现的位置是否为当前位置,若是,则放入新数组 function uniq4(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (arr.indexOf(arr[i]) === i) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null] 同样,因为NaN === NaN为false,所以用indexOf查找NaN结果总是-1,从而在新数组中不会有NaN 2.2.2 findIndex 通过findIndex查找当前元素第一次出现的位置是否为当前位置,若是,则放入新数组 function uniq5(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (arr.findIndex(item => item === arr[i]) === i) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null] 同样,因为NaN === NaN为false,所以用findIndex查找NaN结果总是-1,从而在新数组中不会有NaN 2.3 元素是否存在型 此类型通过判断在新数组中是否存在当前元素来去重 2.3.1 includes includes方法用来判断一个数组是否包含一个指定的值 function uniq6(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (!res.includes(arr[i])) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN] includes使用零值相等算法来确定是否找到给定的元素,所以可以判断NaN是否在新数组中存在 2.3.2 some some方法用来测试数组中是否至少有1个元素通过了被提供的函数测试 function uniq7(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (!res.some(item => item === arr[i])) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN,NaN] 同样,这里仍旧使用了===来比较元素,因为NaN === NaN为false,所以新数组中会有多个NaN 2.4 依托数据结构特性 此类型通过ES6提供的数据结构Map、Set本身不可重复特性来去重 2.4.1 Map ES6提供的Map结构可以用各种类型的值(包括对象)当作键,且键是唯一的 function uniq8(arr) { const map = new Map() for (let i = 0; i < arr.length; i++) { !map.has(arr[i]) && map.set(arr[i], true) } return [...map.keys()] } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN] map.has方法对NaN也有效 2.4.2 Set(ES6 最常用) Set结构的成员的值都是唯一的,没有重复的值。 function uniq9(arr) { return [...new Set(arr)] } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN] 3 补充 上面所说的方法可以使用不同的Api进行改动,比如使用splice方法去除数组元素的地方,我们可以通过filter方法来过滤数组得到新数组; 再比如includes的方法中不用for循环遍历数组,通过reduce方法来代替等等。 总之,方法有很多,但是万变不离其宗 有些去重方法对NaN无效,因为NaN === NaN为false,如果有需求,可以使用Object.is(NaN, NaN)为true来进行修改 实际应用中,最常用的方法就是使用Set,也可以使用第三方库lodash来处理 (编辑:武汉站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |