前言

去重是开发和面试中经常遇到的问题,下面是总结的 11 种去重方法

方法

示例数组

var arr = [1, 2, 4, 5, 5, 2, 1, 1, 4, 6]

set + 解构赋值

这种方法利用了 set 成员唯一的特征和扩展运算符方法实现

function fn1() {
return ([...new Set(arr)]);
}
console.log(fn1());

forEach 循环 + indexOf

先使用 foreach 循环取到每一个元素,在这里也可以改成 for 循环的写法道理是一样的,取到每一个元素后取这个元素的 index 和循环中 index 比较是否一样,一样则 push()

function fn2() {
let temp = []
arr.forEach((item, index) => {
arr.indexOf(item) == index ? temp.push(item) : null
})
return temp
}
console.log(fn2());

filter 过滤

和上一种方法思路差不多,filter 相当于上面的步骤合并到一个方法中实现

function fn3() {
let temp = arr.filter((item, index) => {
return arr.indexOf(item) == index
})
return temp
}
console.log(fn3());

对象键值唯一性

对象的键值因为具有唯一性,所以可以将数组成员作为 key 保存起来,在数组全部循环过一次后,再循环取出对象的 key 添加到一个空白数组中,但是这种方法会导致取出的数组成员数据类型全部转换为文本类型

function fn4() {
let obj = {}
let temp = []
arr.forEach((item, index) => {
obj[item] = index //这一步赋值value其实没有必要,因为最后使用不到
})
for (const key in obj) {
temp.push(key)
}
return temp
}
console.log(fn4());

双重 for 循环

外循环的作用是取到每一个元素,内循环的作用是将外循环取到的元素和其余的元素做对比,如果能取到一样的将后一个删除,要注意的是删除的话需要将内循环的计数 - 1,因为数组的长度也 - 1 了。

function fn5() {
let temp = arr
for (let i = 0; i < temp.length; i++) {
for (let j = i + 1; j < temp.length; j++) {
if (temp[i] === temp[j]) {
temp.splice(j, 1)
j--
}
}
}
return temp
}
console.log(fn5());

indexOf + lastIndexOf

这种方法的思路是如果一个元素查找她的索引,从前获得和从后获得的索引一样,则必然是唯一的,如果不一样说明有重复,删除最后一个并将计数 i-1。

function fn6(){
for(let i =0;i<arr.length;i++){
if(arr.indexOf(i)!=arr.lastIndexOf(i)){
arr.splice(arr.lastIndexOf(i),1)
i--
}
}
return arr
}
console.log(fn6());

sort + 循环

思路是先将数组的内容按照大小排序,然后从第一开始和后一个进行对比,如果一样说明是重复的,将重复的删除并计数 - 1。

function fn7() {
let temp = arr.sort((a, b) => {
return a - b
})
for (let i = 0; i < temp.length; i++) {
if (temp[i] === temp[i + 1]) {
temp.splice(i + 1, 1)
i--
}
}
return temp
}
console.log(fn7());

includes + 循环

思路是先创建一个新数组,然后循环取到每一个元素,如果该元素不在新数组中,就将其添加进去。

function fn8() {
let temp = []
for (let i = 0; i < arr.length; i++) {
if (!temp.includes(arr[i])) {
temp.push(arr[i])
}
}
return temp
}
console.log(fn8());

Map

Map 是 ES6 中特性,是一种字典的数据结构,和对象一样也具有 key 的唯一性

  • map.set 设置 map 的 key
  • map.has 检测是否含有指定的 key,返回一个布尔值
function fn9() {
let map = new Map();
let temp = []
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) { //如果键值不存在,则写入这个键值并添加到数组
map.set(arr[i], false);
temp.push(arr[i]);
}
}
return temp;
}
console.log(fn9());

递归

这个方法和 sort 方法也许相似,先使用 sort 排序,但是是使用递归的思路从后到前删除相同的元素

function fn10() {
let len = arr.length;
let temp = arr.sort(function (a, b) {
return a - b;
});
function loop(index) {
if (index >= 1) {
if (temp[index] === temp[index - 1]) {
temp.splice(index, 1);
}
loop(index - 1)
}
}
loop(len - 1);
return temp;
}
console.log(fn10());

Reduce

reduce 的数组的累加器方法,在本例中 reduce 的第一个参数是一个函数,用来处理每一个元素,第二个参数是一个空数组作为容器,reduce 的循环开始,空数组会被带入 prev,判断 prev 中是否含有当前处理的元素 item,如果已经有了就不做处理,如果没有就将 prev 和 item 合并为一个数组,处理完毕后这个数组会被返回给 reduce 作为下一轮处理的第二个参数,依次循环,最后得到的就是去重后的数组

function fn11() {
return arr.reduce((prev, item) => {
return prev.includes(item) ? prev : [...prev, item]
}, []);
}
console.log(fn11());

总结

数组的去重方法有很多,在使用的时候需要根据自己的需求去选择,比如使用了 sort 的方法的去重只能使用在纯数字数组中,而对象键值去重数组后数组成员都是纯字符串等等。本篇只是简单的方法总结,还有一些没有举例,重点是解决问题思路

javaScript去重的11种方法的更多相关文章

  1. [转]JavaScript去重的6种方法

    Array.prototype.unique1 = function() { var n = []; for(var i = 0; i < this.length; i++) { if (n.i ...

  2. JavaScript中数组去重的几种方法

    JavaScript中数组去重的几种方法 正常情况下,数据去重的工作一般都是由后端同事来完成的,但是前端也要掌握好处理数据的能力,万一去重的工作交给我们大前端处理,我们也不能怂呀.现在我总结了一些去重 ...

  3. js中数组去重的几种方法

    js中数组去重的几种方法         1.遍历数组,一一比较,比较到相同的就删除后面的                 function unique(arr){                 ...

  4. 在WebBrowser中执行javascript脚本的几种方法整理(execScript/InvokeScript/NavigateScript) 附完整源码

    [实例简介] 涵盖了几种常用的 webBrowser执行javascript的方法,详见示例截图以及代码 [实例截图] [核心代码] execScript方式: 1 2 3 4 5 6 7 8 9 1 ...

  5. JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)

    JavaScript继承的6种方法 1,原型链继承 2,借用构造函数继承 3,组合继承(原型+借用构造) 4,原型式继承 5,寄生式继承 6,寄生组合式继承 1.原型链继承. <script t ...

  6. python列表的11种方法

    python列表的11种方法2017年11月24日 03:26:43 Milton-Long 阅读数:254版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.n ...

  7. python 3.x 字典的11种方法

    python 3.x 字典的11种方法2017年11月25日 01:02:11 Milton-Long 阅读数:535 标签: python python字典方法 更多个人分类: python-学习之 ...

  8. Javascript 创建对象的三种方法及比较【转载+整理】

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide/Inheritance_and_the_prototype_chain 本文内容 引 ...

  9. List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇

    最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java ...

随机推荐

  1. Runable与Callable的区别

    Runable与Callable的区别: public interface Callable<V> { V call() throws Exception;//V是Callable返回值的 ...

  2. Red Hat牵头推进NVFS文件系统

    开源Linux 长按二维码加关注~ 上一篇:Linux中几个正则表达式的用法 由 Red Hat 工程师牵头的团队,正在为 Linux/开源社区研究名为 NVFS 的文件系统.NVFS 的目标是成为像 ...

  3. 《Mybatis 手撸专栏》第7章:SQL执行器的定义和实现

    作者:小傅哥 博客:https://bugstack.cn - <手写Mybatis系列> 一.前言 为什么,要读框架源码? 因为手里的业务工程代码太拉胯了!通常作为业务研发,所开发出来的 ...

  4. Java SPI 和 API,傻傻分不清?

    最近新写了一个中间件「运行时动态日志等级开关」,其中使用Java SPI机制实现了自定义配置中心,保证良好的扩展性. 项目地址,走过路过可以点个star :)https://github.com/sa ...

  5. .NET混合开发解决方案11 WebView2加载的网页中JS调用C#方法

    系列目录     [已更新最新开发文章,点击查看详细] WebView2控件应用详解系列博客 .NET桌面程序集成Web网页开发的十种解决方案 .NET混合开发解决方案1 WebView2简介 .NE ...

  6. Java学习笔记-基础语法Ⅱ

    成员变量:类中方法外的变量 局部变量:方法中的变量 注意,成员变量有默认初始值,而局部变量需要赋初始值 Java中虽然没有明确规定类必须首字母大写,但为了规范最好大写(因为自己刚刚写的时候就没看清写错 ...

  7. python操作MySQL,SQL注入的问题,SQL语句补充,视图触发器存储过程,事务,流程控制,函数

    python操作MySQL 使用过程: 引用API模块 获取与数据库的连接 执行sql语句与存储过程 关闭数据库连接 由于能操作MySQL的模块是第三方模块,我们需要pip安装. pip3 insta ...

  8. 一起看 I/O | Flutter 3 正式发布!

    作者 / Tim Sneath, Google Flutter 和 Dart 产品组产品经理 Flutter 3 实现了 Flutter 以移动端为中心扩展到多平台的产品规划,并在今年 I/O 大会的 ...

  9. 讨论两种Redis中Token的存储方式

    摘要:本文讨论一个问题:存储token时,token与对应用户id谁来作为key? 问题起源问题起源于要给公司的后台管理系统添加权限管理,选用的是开源框架shiro,而原本系统上是采用token做了登 ...

  10. 『忘了再学』Shell基础 — 16、位置参数变量

    目录 1.位置参数变量$n 2.位置参数变量$*和$@ 3.位置参数变量$# 位置參数变量的作用主要用于脚本的传参. 位置參数变量的名称和作用都是确定不能改变的,但是该变量的内容是可以更改的,也就是变 ...