JavaScript 数组去重经常出现在前端招聘的笔试题里,比如:

有数组 var arr = ['a', 'b', 'c', '1', 0, 'c', 1, '', 1, 0],请用 JavaScript 实现去重函数 unqiue,使得 unique(arr) 返回 ['a', 'b', 'c', '1', 0, 1, '']

作为笔试题,考点有二:

  1. 正确。别小看这个考点,考虑到 JavaScript 经常要在浏览器上运行,在千姿百态的各种浏览器环境下要保障一个函数的正确性可不是一件简单的事,不信你继续读完这篇博客。

  2. 性能。虽然大部分情况下 JavaScript 语言本身(狭义范畴,不包含 DOM 等延拓)不会导致性能问题,但很不幸这是一道考题,因此面试官们还是会把性能作为一个考点。

在继续往下阅读之前,建议先实现一个自己认为最好的版本。

直觉方案

对于数组去重,只要写过程序的,立刻就能得到第一个解法:

function unique(arr) {
var ret = [] for (var i = 0; i < arr.length; i++) {
var item = arr[i]
if (ret.indexOf(item) === -1) {
ret.push(item)
}
} return ret
}

直觉往往很靠谱,在现代浏览器下,上面这个函数很正确,性能也不错。但前端最大的悲哀也是挑战之处在于,要支持各种运行环境。在 IE6-8 下,数组的 indexOf 方法还不存在。直觉方案要稍微改造一下:

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
} function unique(arr) {
var ret = [] for (var i = 0; i < arr.length; i++) {
var item = arr[i]
if (indexOf(ret, item) === -1) {
ret.push(item)
}
} return ret
}

写到这一步,正确性已没问题,但性能上,两重循环会让面试官们看了不爽。

优化方案

一谈到优化,往往就是八仙过海、百花齐放。但八仙往往不接地气,百花则很容易招来臭虫。数组去重的各种优化方案在此不一一讨论,下面只说最常用效果也很不错的一种。

function unique(arr) {
var ret = []
var hash = {} for (var i = 0; i < arr.length; i++) {
var item = arr[i]
var key = typeof(item) + item
if (hash[key] !== 1) {
ret.push(item)
hash[key] = 1
}
} return ret
}

核心是构建了一个 hash 对象来替代 indexOf. 注意在 JavaScript 里,对象的键值只能是字符串,因此需要 var key = typeof(item) + item 来区分数值 1 和字符串 '1' 等情况。

 使用ES6 更简单:
// ES6
function unique (arr) {
const seen = new Map()
return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}
// or
function unique (arr) {
return Array.from(new Set(arr))
}

从JavaScript 数组去重看兼容性有关问题,及性能优化(摘自玉伯博客)的更多相关文章

  1. 也谈面试必备问题之 JavaScript 数组去重

    Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  2. JavaScript数组去重—ES6的两种方式

    说明 JavaScript数组去重这个问题,经常出现在面试题中,以前也写过一篇数组去重的文章,(JavaScript 数组去重的多种方法原理详解)但感觉代码还是有点不够简单,今天和大家再说两种方法,代 ...

  3. javascript数组去重算法-----3

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. javascript数组去重算法-----2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. javascript数组去重算法-----1

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. javascript数组去重算法-----5

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. javascript数组去重算法-----4(另一种写法__2)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. javascript数组去重算法-----4(另一种写法)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. javascript数组去重算法-----4

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. SpringMVC 理论与有用技术(一) 简单、有用、易懂的几个实例

    SpringMVC先来看一下百度百科中的定义; Spring MVC属于SpringFrameWork的兴许产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应 ...

  2. .NET:CLR via C# The CLR’s Execution Model

    The CLR’s Execution Model The core features of the CLR memory management. assembly loading. security ...

  3. pytest文档1-环境准备与入门

    前言 首先说下为什么要学pytest,在此之前相信大家已经掌握了python里面的unittest单元测试框架,那再学一个框架肯定是需要学习时间成本的. 刚开始我的内心是拒绝的,我想我用unittes ...

  4. JSON数据转换成table表格

    <%@ page contentType="text/html; charset=UTF-8" %> <%@taglib uri="/struts-ta ...

  5. django的过滤和搜索排序功能django-filter

    参考: 1.https://django-filter.readthedocs.io/en/master/guide/usage.html#the-filter 2.https://www.cnblo ...

  6. iOS:第三方数据库文件FMDB的使用

    第三方数据库FMDB •FMDB的使用:在sqlite的基础上,将sqlite中的函数进行封装产生的一个数据库文件. –FMDB的好处是对基本C库的封装,方便使用.同时还提供了多线程操作数据库带来的读 ...

  7. ChartView与LineSeries搭配实现曲线局部缩放功能

    效果图: 上一篇文章实现的时候还不知道有QtChart这个模块......好好看了下资料就想做个例子实现一下这功能,比较了下代码量...恩,直接看代码: Rectangle { id: view_re ...

  8. 度量Web性能的关键指标

    自网站诞生以来,响应速度/响应时间一直都是大家关心的话题,而速度慢乃是网站的一个杀手,正当大家以为四核和宽带能力的提升能够解决这些问题时,Wi-Fi和移动设备为热点移动互联网又悄然兴起. 在2006年 ...

  9. [Node.js] Level 6. Socket.io

    6.2 Setting Up socket.io Server-Side So far we've created an Express server. Now we want to start bu ...

  10. 根据Ip地址与掩码 得出 子网地址与广播地址

    由于给予条件优先,没有直接给出子网地址与广播地址.但是又需要这两个参数,需要我们使用ip 地址与 子网掩码得出子网地址与广播地址.思路如下:       1. 子网地址, ip地址与 子网掩码分别换算 ...