声明

以下方法仅对数组值全部属于 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

参考资料

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

  1. esp8266接收到的数据如何存放到数组中_愉快地学Java语言:第七章 数组

    导读 本文适合Java入门,不太适合Java中高级软件工程师.本文以<Java程序设计基础篇>第10版为蓝本,采用不断提出问题,然后解答问题的方式来讲述.本篇文章只是这个系列中的一篇,如果 ...

  2. python数组类型_一文搞懂Python中的所有数组数据类型

    关于我 编程界的一名小小程序猿,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. 联系:hylinux1024@gmail ...

  3. map的key可以试一个数组吗?_【自考】数据结构第三章,数组,期末不挂科指南,第5篇...

     数组 概念如下 数组可以看成线性表的一种推广,其实就是一种线性表,一维数组又称为向量 数据由一组具有相同类型的数据元素组成,并存储在一组连续的存储单元中 若一维数组中的数据元素又是一维数组结构,则 ...

  4. python三维数组切片_【NumPy学习指南】day4 多维数组的切片和索引

    ndarray支持在多维数组上的切片操作.为了方便起见,我们可以用一个省略号(...)来 表示遍历剩下的维度. (1)举例来说,我们先用arange函数创建一个数组并改变其维度,使之变成一个三维数组: ...

  5. 用数组循环实现矩阵乘法php,array用法 numpy_从创建数组到矩阵运算,一文带你看懂Numpy...

    导读:Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包,其提供了矩阵运算的功能.本文带你了解Numpy的一些核心知识点. 作者:魏溪含 涂铭 张修鹏 如需转载请联 ...

  6. es6 数组合并_对比 ES5,学习 ES6(一)

    一.let.const 之前声明变量都是用的 var,可是 var 有很多问题,比如可以重复声明.没有块级作用域等. ES6 引入了 let 和 const,它们的区别在于: var 可以重复声明,l ...

  7. 微信小程序js数组初始化_微信小程序开发之改变data中数组或对象的某一属性值...

    前言:在小程序的开发中,我们在view中便利data中数组或对象时,很多情况下需要在js中动态改变数组或者对象中某一香的属性值. 效果图: 我给大家总结了案例如下: wxml如下: {{item.we ...

  8. es6 获取本月本年_微信小程序之ES6与事项助手

    本文发表至今已有一段时间,错别字多.文笔混乱.内容过于陈旧.本人建议读者不必细究,大概浏览即可,最新的开发指南还是以官方文档为准,该博文的示例代码经过了重构,已经与官方文档同步,可能与文中的代码片段有 ...

  9. c++ 数组截取_【学习教程】JavaScript中原生Array数组方法详解

    来源 | http://www.fly63.com/article/detial/9692 JS中,数组可以通过阵列构造函数或[]字面量的方式创建.数组是一个特殊的对象,继承自对象原型,但用typeo ...

  10. 如歌将两个数组合并_腾讯50题---合并两个有序数组

    题目描述: 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 ...

最新文章

  1. ES6公用立体轮播组件的封装及使用
  2. 我想自学Linux,需要从哪些方面学起
  3. 24口光纤配线架 cad块_光纤配线架cad画法
  4. SpringMVC用注解写第一个程序HelloSpringMVC
  5. Python--多态与多态性、绑定方法与非绑定方法
  6. Linux分享笔记:查看帮助命令 常用系统工作命令
  7. 毕设题目:Matlab语音识别
  8. TCP/IP-链路层
  9. Shell常用命令大全
  10. AirPlay/ios浅谈
  11. 基础算法:数的三次方根—浮点二分
  12. 二、ArcGIS中shp裁剪dem
  13. Lua二进制chunk
  14. Python实现基于负熵最大判据的FastICA胎心信号分离
  15. ios 高德获取定位_单次定位-获取位置-开发指南-iOS 定位SDK | 高德地图API
  16. 企业/工作室官网 期末作业
  17. 达梦数据库管理工具使用
  18. Kali Linux 秘籍 第九章 无线攻击
  19. C语言入门习题系列二(含答案)
  20. Keil uVision5 MDK(ARM)软件的介绍、下载、安装与注册

热门文章

  1. Kali-DDoS工具集合
  2. 蓦然回首,Java 已经 24 岁了!
  3. 加息 75 个基点落地,市场短暂宣泄后前路依旧黯淡?
  4. CNI网络插件之flannel
  5. [学习报告]《LeetCode零基础指南》第三讲循环-gyro
  6. 4入4出Modbus RTU继电器模块说明书
  7. 产品专利和方法专利对比分析
  8. ES6新特性-前端面试问题
  9. iOS SceneDelegate使用总结
  10. 如何使用云存储以及使用好处