JS数组去重详情


Posted in Javascript onNovember 07, 2021

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来处理

到此这篇关于JS数组去重详情的文章就介绍到这了,更多相关JS数组去重内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
基于jquery库的tab新形式使用
Nov 16 Javascript
jQuery隔行变色与普通JS写法的对比
Apr 21 Javascript
JS+CSS实现的蓝色table选项卡效果
Oct 08 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
Dec 07 Javascript
jQuery实现简单的点赞效果
May 29 Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
Aug 02 Javascript
无法获取隐藏元素宽度和高度的解决方案
Mar 07 Javascript
整理关于Bootstrap排版的慕课笔记
Mar 29 Javascript
AngularJS中使用ngModal模态框实例
May 27 Javascript
jQuery中库的引用方法
Jan 06 jQuery
详解 微信小程序开发框架(MINA)
May 17 Javascript
vue实现图书管理系统
Dec 29 Vue.js
手写实现JS中的new
Nov 07 #Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
You might like
十天学会php之第十天
2006/10/09 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
PHP实现的简单在线计算器功能示例
2017/08/02 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
uploadify 3.0 详细使用说明
2012/06/18 Javascript
JavaScript中window、doucment、body的解释
2013/08/14 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
swtich/if...else的替代语句
2015/08/16 Javascript
js为什么不能正确处理小数运算?
2015/12/29 Javascript
Angularjs中UI Router的使用方法
2016/05/14 Javascript
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
VueJS如何引入css或者less文件的一些坑
2017/04/25 Javascript
vue.js加载新的内容(实例代码)
2017/06/01 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
2018/01/16 Javascript
微信小程序三级联动选择器使用方法
2020/05/19 Javascript
对vux点击事件的优化详解
2018/08/28 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
2020/03/09 Javascript
JavaScript实现公告栏上下滚动效果
2020/03/13 Javascript
详解JavaScript类型判断的四种方法
2020/10/21 Javascript
vue3.0+vue-router+element-plus初实践
2020/12/02 Vue.js
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
2017/08/23 Python
pytorch 中pad函数toch.nn.functional.pad()的用法
2020/01/08 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
在matplotlib中改变figure的布局和大小实例
2020/04/23 Python
基于tensorflow for循环 while循环案例
2020/06/30 Python
CSS3实现可关闭的下拉手风琴菜单效果
2015/08/31 HTML / CSS
利用CSS3把图片变成灰色模式的实例代码
2016/09/06 HTML / CSS
Tripadvisor新西兰:阅读评论,比较价格和酒店预订
2018/02/10 全球购物
清扬洗发水广告词
2014/03/14 职场文书
群众路线查摆问题整改措施
2014/10/10 职场文书
七一活动主持词
2015/06/29 职场文书
2015中学学校工作总结
2015/07/20 职场文书
2015年高中生国庆节演讲稿
2015/07/30 职场文书
Win11运行育碧游戏总是崩溃怎么办 win11玩育碧游戏出现性能崩溃的解决办法
2022/04/06 数码科技