es6 嵌套数组循环_[js]从 ES3 到 ES6 教你如何数组去重

2023-11-05

声明

以下方法仅对数组值全部属于 primitive data type 的情况有效。

ES6

方法一: Set数据结构 + Array.from静态方法

ES6中新增了Set数据结构,类似于数组,但是它的成员都是唯一的 ,其构造函数可以接受一个数组作为参数,如:

let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];

let set = new Set(array);

let deduped = Array.from(set);// `deduped = de + dup(duplication) + ed`

console.log(deduped);

// [1, 2, 3, 4, 5]

方法二:Set数据结构 + 扩展语法(spread syntax)

let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];

let deduped = [...new Set(array)];

console.log(deduped);

// [1, 2, 3, 4, 5]

注意扩展语法对所有可遍历对象均有效

let obj = {'key1': 'value1'};

let array = [...obj];

// TypeError: obj is not iterable

方法三: 箭头函数+es5语法(filter, indexOf)

let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];

let deduped = array.filter((el,i,arr) => arr.indexOf(el) === i);

console.log(deduped);

// [1, 2, 3, 4, 5]

ES5

var array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];

var deduped = array.filter(function(el,i,arr) {

return arr.indexOf(el) === i;

})

console.log(deduped);

// [1, 2, 3, 4, 5]

lt_ES5

var array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3,[1,2],[3,4]];

var deduped = [];

for(var i=0, l=array.length;i

var tmp = array[i];

deduped.indexOf(tmp) === -1 && deduped.push(tmp);

}

console.log(deduped);

// [1, 2, 3, 4, 5]

知识补充——关于indexOf

关于浏览器兼容性

在 IE6-8 下,数组的 indexOf 方法还不存在。

所以如果需要兼容 IE6-8,得自己造一个轮子:

var indexOf = [].indexOf ?

function(arr, item) {

return arr.indexOf(item)

} :

function indexOf(arr, item) {

for (var i = 0; i < arr.length; i++) {

if (arr[i] === item) {

return i

}

}

return -1

}

关于性能——时间复杂度

如果说利用 set 数据结构是一种作弊的方式,那么用 indexOf 就是一种相对低下性能的方式,因为 indexOf 的底层也是一次遍历。嵌套循环会让追求性能极致的人感觉不爽。

① arr 遍历push 到新数组

② 其中每循环一次调用数组的 indexOf 方法,又会是一次遍历

所以,相当于两次循环嵌套,遍历复杂度为O(n2)

这种情况下,为追求性能,更好的实现方式为:利用对象 key 的唯一性处理。首先将数组转换为对象,其次将对象转换为去重后的数组。

比如:

var songs = [

{name:"都选C",artist:"大鹏"},

{name:"都选C",artist:"大鹏"},

{name:"塑料袋",artist:"乔杉"},

{name:"塑料袋",artist:"乔杉"},

{artist:"乔杉",name:"塑料袋"}

];

function unique(songs){

let result = {};

let finalResult=[];

// 数组转换为对象,利用对象key的唯一性去重

songs.forEach(function(song, i){

result[song.name]=song;

})

// 将对象还原为去重后的数组

Object.keys(result).forEach(function(key, i){

finalResult.push(result[key]);

})

return finalResult;

}

console.log(unique(songs));

// 注明:偷了个懒 forEach 的性能比 for 循环慢好多。

// 参考:https://github.com/jawil/blog/issues/2

2017-11-16 更新。实际上这个用了至少两次循环(虽然不是循环嵌套),但仍然是低效的。因为最简单的数组去重只需要用一层循环即可。

更为复杂的案例可以看笔者写的这个demo

参考资料

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

es6 嵌套数组循环_[js]从 ES3 到 ES6 教你如何数组去重 的相关文章

随机推荐

  • 通过群晖 DSM 的 “装载远程文件夹(CIFS)” 功能来装载局域网中的 Win7 主机的指定文件或盘符...

    今天下午有空 就整理下电脑和 DSM 里的文件和资料 于是想把电脑里的几个盘 映射 到 DSM 的 File Station 中 以方便数据的搬移 这个 映射 就是通过 DSM 里 File Station 的 装载远程文件夹 来实现的 早
  • 性能测试连载 (9)-压测实战分析性能拐点

    咨询微信 uhz2008 概述 本文对百度进行一次实战压测 验证一下理论知识 分析一下性能拐点 操作 第一次实验 200并发 并发200 不限迭代次数 同时在请求下面加RPS定时器 目的是在200线程下 将RPS逐步增加到1000 S 并持
  • Linux磁盘挂载

    概念 挂载 所谓挂载就是利用一个目录当成进入点 将磁盘分区的数据放在该目录下 也就是说 进入该目录就可以读取该分区的意思 Linux系统最重要的是根目录 因此根目录一定需要挂载到某个分区 至于其他的目录则根据需要挂载到不同的分区 假设硬盘分
  • 推荐一款我最近爱上的网页版文库(编辑器)——语雀yuque.com

    推荐一款由于工作接触然后热爱上的文库 语雀 语雀 https www yuque com 一开始它是阿里内部的文档库 后来随着它的功能升级 升级 升级 我恨不得把自己以前散落在各地的笔记 各种文件都搬上去 甚至最近已经弃用axureRP和s
  • 微信二次分享链接,出现config:invalid signature错误的解决方法

    当开发微信时需要做特定的页面做分享时 根据官方提供的jssdk php文件创建的签名数据包调试时 大家碰到的最多的错误而且解决最麻烦的大概就是signature错误了 分享时提示错误 errMsg config invalid signat
  • 单链表的各种操作,对于初学者来说,更容易理解

    include
  • Oracle11g 数据库提示ORA-28002: the password will expire within

    Oracle11g 数据库提示ORA 28002 the password will expire within 7 days 是说密码过期 oracle11g中默认在default概要文件中设置了 PASSWORD LIFE TIME 1
  • 批量修改mathtype中的公式字体、大小

    目录 一 保存格式文件 二 批量修改 一 保存格式文件 随便双击打开一个公式 点击菜单栏大小 定义 然后根据自己的需求修改参数 修改完成后点击确定 点击菜单栏预设 公式预设 保存到文件 选择一个保存的位置并命名 二 批量修改 下面就对全文公
  • 怎么导入别人的项目运行部署搭建Java项目springboot代码eclipse idea的心得实操

    调过无数代码 就发现没有运行不了的代码 这些代码也是我实践经验的来源 从最开始的servlet 到现在的springcloud 每一种类型的项目都有其特定的导入部署方式 如果是idea或者eclipse 按如下操作 按项目类型分两种情况部署
  • 内网穿透的应用-如何搭建WordPress博客网站,并且发布至公网上?

    文章目录 如何搭建WordPress博客网站 并且发布至公网上 概述 前置准备 1 安装数据库管理工具 1 1 安装图形图数据库管理工具 SQL Front 2 创建一个新数据库 2 1 创建数据库 2 2 为数据库创建一个用户 3 安装P
  • 如何优雅的使用fbx sdk

    include 头文件 设置lib目录 添加libfbxsdk lib 复制粘贴dll文件 运行平台一定要 大写加粗 一定要 设置为x64 添加宏FBXSDK SHARED 否则会出各种莫名其妙的问题
  • 【java基础】HashMap源码解析

    文章目录 基础说明 构造器 put方法 无扩容 无冲突 put方法 无冲突 有扩容 put方法 有冲突 无树化 put方法 有冲突 树化 remove方法 树退化 常见方法 总结 基础说明 HashMap 是一个散列表 它存储的内容是键值对
  • Go语言学习15-基本流程控制

    基本流程控制 流程控制对比 Go 和 C 基本流程控制 1 代码块和作用域 2 if 语句 3 switch语句 3 1 表达式switch语句 3 2 类型switch语句 4 for 语句 4 1 for 子句 4 2 range 子句
  • 什么是三极管的倒置状态及其作用!

    1 什么是三极管的倒置状态 集电结正偏 发射结反偏 为倒置状态 集电结正偏 发射结正偏 为饱和状态 集电结反偏 发射结反偏 为倒截止态 集电结反偏 发射结正偏 为放大状态 2 对三极管倒置状态的分析 实际上 当NPN型三极管的三个电极电位关
  • BUUCTF-Reverse:SimpleRev(算法分析题)

    题目地址 https buuoj cn challenges SimpleRev 查壳 得知消息 ELF 64 直接拖进ida64分析 int cdecl noreturn main int argc const char argv con
  • h5和APP实现交互(安卓-ios)

    h5调用APP 的方法 taskCallback是和APP端协议的函数名 安卓 window PlatformCurrency taskCallback 测试数据 ios window webkit messageHandlers task
  • 使用ffmpeg合并多个视频文件

    由于腾讯视频将一个视频分割成多个20M左右的小文件 所以必须合并起来成为一个完整视频文件 用什么工具来合并这些文件呢 想到了已经安装好的ffmpeg 开源免费 又是现成的 两种方法 方法1 直接写文件名 使用 来分割 ffmpeg i co
  • Java基础系列:NIO编程

    俗世游子 专注技术研究的程序猿 说在前面的话 聊完了Socket编程 我们来聊一聊关于NIO方面的话题 当然在这里只会介绍用的比较广泛的类 方法 其他用的不多的 就不多介绍了 用到的时候查API就好了 本节我们聊个大概内容 明白该如何使用
  • 解决qt里面添加的信号与槽不起作用的办法

    今天 在qt界面上新加了个checkbox 再加上信号与槽 发现竟然没响应 以前遇到过这个问题 没记录下来 其实很简单 把断点放在起作用的slot里面 发现它的前一步是类名 qt static metacall 而这个断点在Moc 类名 c
  • es6 嵌套数组循环_[js]从 ES3 到 ES6 教你如何数组去重

    声明 以下方法仅对数组值全部属于 primitive data type 的情况有效 ES6 方法一 Set数据结构 Array from静态方法 ES6中新增了Set数据结构 类似于数组 但是它的成员都是唯一的 其构造函数可以接受一个数组