Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JS数组去重!!!一篇不怎么靠谱的"深度"水文

JS数组去重!!!一篇不怎么靠谱的"深度"水文

作者头像
CRPER
发布于 2018-08-28 08:44:01
发布于 2018-08-28 08:44:01
63600
代码可运行
举报
文章被收录于专栏:CRPER折腾记CRPER折腾记
运行总次数:0
代码可运行

前言

数组去重,这是一个老梗了...今天我又拿出来说了... 我们在考虑全面一点的情况下,数组去重的实现,比如针对NaN,undefined,{}; 这其中涉及的知识点挺多,不信跟着走一波; 这里不考虑浏览器兼容性这些破问题,因为涉及ES5&6


基础版-只包含一些可以直接比较的数值

测试数组

[1,1,'','','e','e',true,'true',true,false,false,'false',undefined,'undefined',undefined,null,'null',null]

  • [ES5]万能的for方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueUseFor(array) {
  var temp = []; //一个临时数组

  //遍历当前数组
  for (var i = 0, j = array.length; i < j; i++) {
    //很直白,新数组内判断是否有这个值,没有的情况下,就推入该新数组
    temp.indexOf(array[i]) === -1 ? temp.push(array[i]) : '';
  }
  return temp;
}

// result: [1, "", "e", true, "true", false, "false", undefined, "undefined", "null", null]复制代码
  • [ES5]内置的forEach方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueUseForEach(array) {
  // 传入值必须存在,且长度小于等于1的时候直接返回数组
  if (array && array.length <= 1) {
    return array;
  } else {
    var temp = []; //一个临时数组
    //遍历当前数组
    array.forEach(function (value, index) {
      temp.indexOf(value) == -1 ? temp.push(value) : '';
    })
    return temp;
  }
}
// result: [1, "", "e", true, "true", false, "false", undefined, "undefined", "null", null]复制代码
  • [ES6]内置的for-of方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueUseForOf(array) {
  const temp = []; //一个临时数组
  // 传入值必须存在,且长度小于等于1的时候直接返回数组
  if (array && array.length <= 1) {
    return array;
  } else {
    //遍历当前数组
    for (let x of array) {
      temp.indexOf(x) === -1 ? temp.push(x) : '';
    }

  }
  return temp;
}
// result: [1, "", "e", true, "true", false, "false", undefined, "undefined", "null", null]

进阶版- 包含NaN,undefined,null

测试数组

[1,1,'true',true,true,5,'F',false, undefined, null,null,undefined, NaN, 0, 1, 'a', 'a', NaN,'NaN']

知识点

  • NaN有两中通用判定方法和数组中一种判定方法:
    • 一个是绝对不全等于(===)自身
    • 一个是ES6isNaN()
    • 数组原型链上的Array.prototype.includes()
  • [ES5]: 不等特性,需要借助占位符
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueUseNotAllEqual(array) {

  var temp = [], //一个临时数组
      mark = true; // 标识位

  //遍历当前数组
  for (var i = 0, j = array.length; i < j; i++) {
    // 标识位的作用就是用来判断是否存在NaN,第一次找到保留到新数组中
    // 然后标识位置改为false是为了再次找到的时候不推入数组
    if (array[i] !== array[i]) {
      // 这里的不等特性,也可以用isNaN判断[ES6]
      mark && temp.indexOf(array[i]) == -1 ? temp.push(array[i]) : '';
      mark = false;

    } else
      temp.indexOf(array[i]) == -1 ? temp.push(array[i]) : '';

  }
  return temp;
}

// result: [1, "true", true, 5, "F", false, undefined, null, NaN, 0, "a", "NaN"]
  • [ES6]内置Array.prototype.includes()大法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueCompareUseIncludes(array) {
  // 传入值必须存在,且长度小于等于1的时候直接返回数组
  if (array && array.length <= 1) {
    return array;
  } else {
    let temp = []; //一个临时数组
    //遍历当前数组
    for (let x of array) {
      // includes() 方法用来判断当前数组是否包含某指定的值,如果是,则返回 true,否则返回 false。
      temp.includes(x) ? '': temp.push(x) ;
    }
    return temp;
  }
}

// result: [1, "true", true, 5, "F", false, undefined, null, NaN, 0, "a", "NaN"]
  • [ES6] Array.from或拓展运算符[...]结合Set大法

知识点

  • Set的值具有唯一性,内部会自动===比较,是可迭代对象(iterable),有点特殊的是NaN这货虽然有不全等的特性,在Set里面认为是相同的,所以只能有一个
  • Array.from...可以把类似数组【nodelist or arguments】这类可迭代的对象中转为一个标准的数组
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Array.from + Set的方法
Array.from(new Set([1,1,'true',true,true,5,'F',false, undefined, null,null,undefined, NaN, 0, 1, 'a', 'a', NaN,'NaN']))
// resule: [1, "true", true, 5, "F", false, undefined, null, NaN, 0, "a", "NaN"]


// ... + Set的方法
[...new Set([1,1,'true',true,true,5,'F',false, undefined, null,null,undefined, NaN, 0, 1, 'a', 'a', NaN,'NaN'])]
//result: [1, "true", true, 5, "F", false, undefined, null, NaN, 0, "a", "NaN"]

高阶版- 包含{},NaN,undefined,null

测试数组

[1,1,'true',true,true,5,'F',false, undefined, null,null,undefined, NaN,{},{},'{}', 0, 1, 'a', 'a', NaN]

知识点

  • {}的比较真心不好做,有残缺性的比较可以这样写 JSON.stringify({}) == '{}'
  • 一个比较完美的方案是借助for in结合原型链的toString来判断
  • [ES5]for-in + call + for方案
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueUseForIn(array) {
  var temp = [];
  var emptyObjectMark = true; // 标识位
  var NaNObjectMark = true; // 标识位
  // 判断空对象,这块判断折腾了许久
  function isEmptyObject(object) {
    if (Object.prototype.toString.call(object) === "[object Object]") {
      for (var i in object) {
        // 存在属性或方法,则不是空对象
        return false
      }
      return true;
    } else {
      return false;
    }
  }

  // 传入值必须存在,且长度小于等于1的时候直接返回数组
  if (array && array.length <= 1) {
    return array;
  } else {
    //遍历当前数组
    for (var i = 0, j = array.length; i < j; i++) {
      // 标识位的作用就是用来判断是否存在NaN和空对象,第一次找到保留到新数组中
      // 然后标识位置改为false是为了再次找到的时候不推入数组
      if (isEmptyObject(array[i])) {
        emptyObjectMark && temp.indexOf(array[i]) == -1 ? temp.push(array[i]) : '';
        emptyObjectMark = false;
      } else if (array[i] !== array[i]) {
        NaNObjectMark && temp.indexOf(array[i]) == -1 ? temp.push(array[i]) : '';
        NaNObjectMark = false;
      } else
        temp.indexOf(array[i]) == -1 ? temp.push(array[i]) : '';

    }
    return temp;

  }
}

// result:[1, "true", true, 5, "F", false, undefined, null, NaN, Object, "{}", 0, "a"]

拓展版:多维数组扁平化再去重;

回应:

留言板的小伙伴说去重深度不够。。2017/5/12

测试数组

[1, 1, [['true', true, true, [5, 'F'], false], undefined], null, null, [undefined, NaN, {}], {}, '{}', 0,1, 'a','a', NaN]

知识点

  • 数组扁平化用了递归实现
  • 代码也考虑了默认参数,防止不传递参数的时候报错
  • [ES5]for-in + call + for + 递归扁平化方案
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function uniqueArrayWithFlattern(array) {
  var _array = array || []; // 保存传参
  // 判断空对象,这块判断折腾了许久
  function isEmptyObject(object) {
    if (Object.prototype.toString.call(object) === "[object Object]") {
      for (var i in object) {
        // 存在属性或方法,则不是空对象
        return false
      }
      return true;
    } else {
      return false;
    }
  }



  // 遍历查询判断,扁平化数组
  function forArrayFlattern(arr) {

    for (var m = 0, n = arr.length; m < n; m++) {
      if (Array.isArray(arr[m])) {
        var _tempSpliceArr = _array.splice(m, 1)[0];
        _array = _array.concat(_tempSpliceArr);
        return forArrayFlattern(_array);
      }
    }
    return uniqueArr(_array);
  }


  // 传入值必须存在,且长度小于等于1的时候直接返回数组
  if (_array && _array.length <= 1) {
    return _array
  } else {
    if (Array.isArray(_array)) {
      return forArrayFlattern(_array)
    } else {
      return _array;
    }
  }

  // 数组去重
  function uniqueArr(_array) {
    var temp = [];
    var emptyObjectMark = true; // 标识位
    var NaNObjectMark = true; // 标识位
    console.log(_array.length)
    //遍历当前数组
    for (var a = 0, b = _array.length; a < b; a++) {
      // 标识位的作用就是用来判断是否存在NaN和空对象,第一次找到保留到新数组中
      // 然后标识位置改为false是为了再次找到的时候不推入数组

      console.log(_array[a]);
      if (isEmptyObject(_array[a])) {
        emptyObjectMark && temp.indexOf(_array[a]) == -1 ? temp.push(_array[a]) : '';
        emptyObjectMark = false;
      } else if (_array[a] !== _array[a]) {
        NaNObjectMark && temp.indexOf(_array[a]) == -1 ? temp.push(_array[a]) : '';
        NaNObjectMark = false;
      } else {
        temp.indexOf(_array[a]) === -1 ? temp.push(_array[a]) : '';
      }
    }
    console.log(temp);
    return temp;
  }
}

// result:[1, null, Object, "{}", 0, "a", NaN, undefined, "true", true, false, 5, "F"]
// 用ES6来写的话,应该代码量可以稍微再精简些

总结

相信各位小伙伴把这个弄懂了之后,各种面试中的花样数组去重要求对你来说都不是很坑了;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年05月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
云智AI预付费资源包 限时8折优惠!
吼吼吼~ 云智AI 预付费资源包已经正式上线啦!!!从现起至1月31日限时8折优惠中~
腾讯云AI
2018/11/21
9.5K0
重磅 | 腾讯云文字识别6项新服务限时免费公测,4项功能重大升级
港澳台通行证识别、火车票识别、出租车发票识别、机票行程单识别、定额发票识别、购车发票识别,详细内容见接口文档(https://cloud.tencent.com/document/product/866/33515)。开通和调用方式请参考快速接入指引(https://cloud.tencent.com/document/product/866/34681);
腾讯云AI
2019/08/21
4.6K0
重磅 | 腾讯云文字识别6项新服务限时免费公测,4项功能重大升级
实时音视频开发学习15 - 计费问题
腾讯云计费方式分为基础计费、增值服务计费和免费试用。其中基础计费包括语音通话额直播、视频通话和直播,增值服务主要为云端录制,采用旁路直播推流的方式使用云直播的能力并提供全程录制功能,录制的文件可以存储到云点播平台。
金林学音视频
2020/08/30
2.5K0
腾讯云服务器计费模式包年包月和按量付费区别对比
阿里云CVM云服务器计费模式分为包年包月和按量付费两种方式,腾讯云百科分享包年包月、按量付费区别对比:
上云小秘书
2019/08/23
8.4K0
腾讯云服务器计费模式包年包月和按量付费区别对比
实时音视频 TRTC 常见问题汇总---计费篇
TRTC 是腾讯云基于 QQ 十多年来在音视频通话技术上积累,结合腾讯浏览服务 TBS WebRTC 能力与腾讯实时音视频 SDK ,为客户提供多平台互通高品质可定制化的 实时音视频互通服务 解决方案。
TRTC小百科
2021/09/13
5.5K0
腾讯云文字识别使用笔记0811-计费概述
腾讯云文字识别 OCR 提供预付费和后付费两种计费模式,开通后默认使用后付费的计费模式。如果您拥有免费资源包或者付费资源包,将优先对资源包进行扣减,资源包耗尽后自动转入后付费(月结)的方式。
算法发
2020/08/11
2.7K0
借你一双“慧眼”:一文读懂OCR文字识别︱技术派
摘要:在日常生活工作中,我们难免会遇到一些问题,比如自己辛辛苦苦写完的资料,好不容易打印出来却发现源文件丢了;收集了一些名片,却要一个一个地录入信息,很麻烦;快递公司的业务越来越好,但每天需要花费很多时间登记录入运单,效率非常的低。
腾讯云AI
2018/07/16
11.5K1
借你一双“慧眼”:一文读懂OCR文字识别︱技术派
CPS推广奖励新手常见问题说明
(1)新客户首次付费下单,购买指定返佣产品为客户首购,按星级会员返佣。老客户复购/续费、升级订单不参与返佣。
腾讯云-推广奖励
2019/07/08
18.5K0
CPS推广奖励新手常见问题说明
实时音视频 TRTC 常见问题汇总——计费案例
TRTC 是腾讯云基于 QQ 十多年来在音视频通话技术上积累,结合腾讯浏览服务 TBS WebRTC 能力与腾讯实时音视频 SDK ,为客户提供多平台互通高品质可定制化的 实时音视频互通服务 解决方案。
TRTC小百科
2021/09/27
1.5K0
Serverless Wordpress 系列建站教程(三)
从前面两篇教程文章里,我们可以了解到 Serverless WordPress 的低门槛部署,免运维等功能优势。而建站场景中,开发者关注的另一个重点则是成本问题,Serverless 架构究竟如何计费,比起传统模式,它的优势究竟在哪里?本篇文章中,我们将为您做出详细介绍。 使用资源 首先,我们再回顾一下 Serverless WordPress 所用到的云端服务: 模块说明SCF 云函数负责 Serverless Wordpress 的接入层实现,从而运行 WordPressAPI 网关WordPress
腾讯云serverless团队
2021/03/11
1.7K0
华哥有约第二期:云开发“三大件”&环境共享
「华哥有约」是云开发Cloud Base官方出品的问答专栏,将由社区产品经理“华哥”分主题从不同维度解答云开发的热门门问题、剖析常见误区,帮助开发者更高效地使用云开发。
腾讯云开发TCB
2021/08/31
7640
华哥有约第二期:云开发“三大件”&环境共享
iOS音视频接入- TRTC计费及套餐介绍
实时音视频 TRTC 的服务项根据服务类型划分为基础服务和增值服务两大类。除了这两大类之外,从2019年10月11日起,首次在实时音视频控制台创建应用的腾讯账号,还可有10000分钟的免费试用,也就是第一次使用实时音视频这个产品就会有免费试用。有免费试用可以先试用,试用之后再看使用效果在决定是否续费套餐及购买活动的超值套餐。
小明同学接音视频
2020/10/19
3.5K0
iOS音视频接入- TRTC计费及套餐介绍
腾讯云OCR文字识别“测评”
前不久有朋友为了方便工作,问我“怎么把图片中的文字提取出来”,我当时就想到手机QQ扫一扫刚好可以实现这个功能,就让他先将图片传到手机,然后再用手机QQ扫一扫 。
神无月
2018/06/01
21.3K0
腾讯云OCR文字识别“测评”
可开票金额不一致常见原因及核对方法
大家在购买腾讯云资源后,一般都需要申请发票用于报销或月底对账,而在申请发票时会遇到腾讯云帐号的可开票金额的核对问题,本文章基于这个主题,分享关于可开票金额不一致的常见原因及核对方法。
waynezzhu
2020/11/11
2.8K0
可开票金额不一致常见原因及核对方法
彭碧发:腾讯云文字识别OCR技术构建和应用
2019年9月7日,云+社区(腾讯云官方开发者社区)主办的技术沙龙——AI技术原理与实践,在上海成功举行。现场的5位腾讯云技术专家,在现场与开发者们面对面交流,并深度讲解了腾讯云云智天枢人工智能服务平台、OCR、NLP、机器学习、智能对话平台等多个技术领域背后架构设计理念与实践方法。
腾讯云开发者社区技术沙龙
2019/09/12
4.8K0
彭碧发:腾讯云文字识别OCR技术构建和应用
腾讯云OCR文字识别“测评”
本文目录 前言 API选择 腾讯云OCR 简介: 请求头: 返回内容 计费方式 调用注意事项 PHP源码分享 使用体验: 前言 前不久有朋友为了方便工作,问我“怎么把图片中的文字提取出来”,我当时就想到手机QQ扫一扫刚好可以实现这个功能,就让他先将图片传到手机,然后再用手机QQ扫一扫 告诉他之后,我也感觉有点不妥,要是一张两张还好,要是图片多了,一直把图片传到手机,用手机QQ扫是极其影响工作效率的,然后就去百度了下看看有没有那种在线识别的,居然没找到。于是乎,作为一个“程序员”,哪能被这些东西给难倒
神无月
2018/06/06
53.1K1
产品分享|腾讯云AI文字识别从0到1实现通信行程卡识别
疫情防控常态化下,学校为了保证孩子身体健康和安全,要求所有入校人员提供通信行程码并审核。但是通过人工审核的方式,不仅工作量极大且容易出错。作为一名软件开发工程师,我开始思考并着手调研,希望可以通过更智能的方式来解决。 在调研过程中,发现腾讯云AI文字识别产品推出了健康码OCR、行程卡OCR等多种自动化识别能力,刚好契合智能识别这个现实问题。但是识别出来的结果是否准确呢? 查阅了官方介绍资料,发现腾讯云AI联合腾讯优图实验室针对文本检测和文字识别关键技术进行了优化和创新。在文本检测技术方面进行了深度优化,提出
腾讯云TI平台
2022/07/19
2.6K0
产品分享|腾讯云AI文字识别从0到1实现通信行程卡识别
最佳实践|用腾讯云AI文字识别实现企业资质证书识别
企业经营活动中,资质证书是证明企业生产能力的必要证件,也是企业入驻各类平台、组织项目申报等必须提交的,这里面包括营业执照、税务登记证、生产许可证、高新技术企业认定证书等等。在日常工作中,以平台类企业入驻为例,要求企业上传对应的资质证书然后进行审核,但由于企业资质证书种类繁多,各行各业的资质证书都有差异,没有统一的板式,通过人工审核工作量巨大且很容易出错。
腾讯云AI
2022/07/22
6.6K1
最佳实践|用腾讯云AI文字识别实现企业资质证书识别
【独家】一文读懂文字识别(OCR)
前言 文字识别是计算机视觉研究领域的分支之一,归属于模式识别和人工智能,是计算机科学的重要组成部分 本文将以上图为主要线索,简要阐述在文字识别领域中的各个组成部分。 一 ,文字识别简介 计算机文字识别,俗称光学字符识别,英文全称是Optical Character Recognition(简称OCR),它是利用光学技术和计算机技术把印在或写在纸上的文字读取出来,并转换成一种计算机能够接受、人又可以理解的格式。OCR技术是实现文字高速录入的一项关键技术。 在OCR技术中,印刷体文字识别是开展最早,技术
数据派THU
2018/01/29
24.5K1
CPS 推广奖励规则
推广大使应在腾讯云推广许可范围内,使用正当的手段方式进行推广,不应进行任何欺骗或虚假性质的推广行为,包括但不限于:
腾讯云-推广奖励
2018/11/01
241.5K147
CPS 推广奖励规则
推荐阅读
相关推荐
云智AI预付费资源包 限时8折优惠!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验