距离上次发文,已经有一段时间了,最近工作比较忙,这不眼看快双十一了,就相当于给大家一些福利吧!

一、什么是数组去重

简单说就是把数组中重复的项删除掉,你 GET 到了吗 ?下面我将简单介绍下几种基本的方法及其优缺点。

二、方法汇总

  • 两层循环

** 无相同值直接 push 进新数组,有相同的值则直接跳过本次内部循环 **

/*
* @param {Array} arr -要去重的数组
* @param {Array} result -初始化结果数组
*/
const unique = (arr, result = []) => {
const len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] === arr[j]) {
// 相等则直接跳过
j = ++i;
}
}
result.push(arr[i]);
}
return result;
}

** 相同的做标记,与新数组作比较,没有则插入 **

/*
* @param {Array} arr -要去重的数组
* @param {Array} result -初始化结果数组
*/
const unique = (arr, result = []) => {
result.push(arr[0]);
const len = arr.length;
let rLen = result.length; for (let i = 1; i < len; i++) {
let flag = false;
for (var j = 0; j < rLen; j++) {
if (arr[i] === result[j]) {
flag = true;
break;
}
}
if (!flag) {
rLen++;
result.push(arr[i]);
}
}
return result;
}

** 原地算法(在数组本身操作) **

const unique = arr => {
const len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j,1);
len--;
j--;
}
}
}
return arr;
};

看似代码代码简单,实则内存占用高,不实用

  • 单层循环

** 对象键不能重复 **

const unique = (arr, result = []) => {
const obj = {};
const len = arr.length;
for (let i = 0; i< len; i++) {
if (!obj[arr[i]]) {
// 键没有,则添加
obj[arr[i]] = 1;
result.push(arr[i]);
}
}
return result;
};

这种方法无法判断 '1'1 等类型,解决方案:

  1. 添加判断数据类型,比如 typeofobj[typeof arr[i] + arr[i]] 不过这还是判断不了 ['1'][1],因为这被相加后,结果都一样
  2. 添加 JSON.stringify() 对结果进行去格式化,这时就可以判断了

** 排序后比较前后两位,不相等则添加进新数组 **

const unique = (arr, result = []) => {
arr.sort();
result.push(arr[0]);
const len = arr.length;
let rLen = result.length;
for (let i = 1; i < len; i++) {
if (arr[i] !== result[rLen - 1]) {
result.push(arr[i]);
rLen++;
}
}
return result;
}

方法比较直接

** 原地算法(排序后比较前后两位,相等则删除) **

const unique = (arr) => {
arr.sort();
let len = arr.length;
for (let i = 1; i < len; i++) {
if (arr[i] === arr[i - 1]) {
arr.splice(i, 1)
len--;
}
}
return arr;
}

不消耗额外的空间

  • 偷懒的节奏

** indexOf 判断数组元素第一次出现的位置是否相同 **

const unique = (arr, result) => {
arr.forEach((item, index, array) => {
if(array.indexOf(item) === index) {
result.push(item);
}
});
return result;
} // 使用ES6 filter
const unique = (arr) =>
arr.filter((item, index) => array.indexOf(item) === index);

使用ES6 方法更简洁性能更好

** indexOf 的ES6 方法通过 includes 判断新数组中是否有该元素 **

const unique = (arr, result) => {
arr.forEach((item, index, array) => {
if(!result.includes(item)) {
// 或者 result.indexOf(item) === -1
result.push(item);
}
});
return result;
}

建议使用 includes

** Map 数据结构,不懂 Map 的自行解决,传送门 **

const unique = arr => {
const map = new Map();
return arr.filter((item) => !map.has(item) && map.set(item, 1));
}

对象关系映射可以设置不同类型的键,使之很快能收集 arr 中不一样的数据

** Set 数据结构,不允许出现重复数据,而且 Set 支持解构 传送门 **

const unique = arr => Array.from(new Set(arr));

// 或者通过 ES6 的 ...解构
const unique = arr => [...new Set(arr)];

简单粗暴

** reduce,给定初始值,根据数组循环给出最终值 **

const unique = (arr, result = []) => arr.reduce((prev,curr) => prev.includes(curr) ? prev : [...prev, curr], result);

三、总结

方法已经说了差不多了,就看你怎么用了,其中有一些差不多的方法,只是给了说明,没给具体的例子,希望大家自己去试一下,告辞!

JS数组专题2️⃣ ➖ 数组去重的更多相关文章

  1. JS数组专题1️⃣ ➖ 数组扁平化

    一.什么是数组扁平化 扁平化,顾名思义就是减少复杂性装饰,使其事物本身更简洁.简单,突出主题. 数组扁平化,对着上面意思套也知道了,就是将一个复杂的嵌套多层的数组,一层一层的转化为层级较少或者只有一层 ...

  2. LeetCode:数组专题

    数组专题 有关数组的一些 leetcode 题,在此做一些记录,不然没几天就忘光光了 二分查找 双指针 滑动窗口 前缀和/差分数组 二分查找 本文内容摘录自公众号labuladong中有关二分查找的文 ...

  3. js面试题之数组去重对比

    最近看一些面试题,很多都提到了数组去重,用的最多的不外乎就是下面这个例子 arr.filter(function(value,index,arr){ return arr.indexOf(value, ...

  4. 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)

    目录 这是<前端总结·基础篇·JS>系列的第二篇,主要总结一下JS数组的使用.技巧以及常用方法. 一.数组使用 1.1 定义数组 1.2 使用数组 1.3 类型检测 二.常用技巧 2.1 ...

  5. JS 使用 splice() 对数组去重

    一 问题 有如下 js 数组 connect_clients,需要在去掉所有元素中 user_id, goods_id 这两者的值都相同的元素. [ { id: 'eff040fb-92bc-4f24 ...

  6. JS 两个对象数组合并并去重

    JS两个对象数组合并并去重 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  7. JS如何去掉一个数组的重复元素 (数组去重)

    一.思路如下: 定义一个新数组,将老数组遍历一遍,再进行判断,如果新数组里面没有老数组的元素就添加,否则就不添加,最终输出整个新数组. 二.代码如下: var arr = ["a" ...

  8. 亲测有效JS中9种数组去重方法

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14555831.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  9. js array.filter实例(数组去重)

    语法: 循环对数组中的元素调用callback函数, 如果返回true 保留,如果返回false 过滤掉,  返回新数组,老数组不变 var new_array = source_array.filt ...

随机推荐

  1. [Xcode 实际操作]七、文件与数据-(22)使用OCR光学字符识别技术识别银行卡号码

    目录:[Swift]Xcode实际操作 本文将演示如何使用光学字符识别技术,识别信用卡上的卡号. OCR技术是光学字符识别的缩写(Optical Character Recognition), 是通过 ...

  2. ubuntu 安装R 语言

    我个人的环境是 ubuntu 12.04 64 位桌面版. 我自己在安装R 语言时,发现它依赖的库真不是一般的多,所以我在这里简单记录一下我整个安装过程 首先你需要安装 apt-get install ...

  3. 在maven中引入本地jar包的方法

    一.第一种方式: 1.电脑安装maven 2.下载jar.例如 gj.jar 3.把jar随便放一个位置 4.在jar包目录下打开cmd输入: mvn install:install-file -Df ...

  4. sql数据库查询结果字段包含换行符导致复制到Excel发生错位问题的解决

    问题描述:在工作过程中,有时会遇到这样的问题,写好sql查询语句在数据库中查询数据,看到行数(比如说是1000行),但是把查询结果复制到Excel里面,却发生了行列错位问题,而导致Excel里面的行数 ...

  5. CSS实现多行文字限制显示

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  6. 洛谷1052(路径压缩后简单dp)

    同POJ3744写法都是一样的. 距离太长无意义可以压缩,注意不是随便压的,想一想可以跟%T发生关系. #include <cstdio> #include <cctype> ...

  7. 接口测试02 - 无法绕过的json解析

    概述: 先瞧一下什么是json.JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式. 它基于ECMAScript(w3c定制的js规范)的一个子集 ...

  8. 115 Distinct Subsequences 不同子序列

    给定一个字符串 S 和一个字符串 T,求 S 的不同的子序列中 T 出现的个数.一个字符串的一个子序列是指:通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串.(譬如," ...

  9. Win10系统特别卡的一个原因

    我遇到的Win10特别卡的原因是它自带的一个杀毒软件 迈克菲(McAfee)导致的,在卸载之前电脑真的特别卡,打开一个窗口都卡,,卸载了之后瞬间感觉电脑飞起来了.... 当然还有很多原因会导致电脑卡, ...

  10. 牛客网Java刷题知识点之什么是JSP的3大常用指令、JSP的6大哪些动作、JSP中include指令和include动作有什么区别

    不多说,直接上干货! JSP的3大常用指令 包含指令(Include directive):用来包含文件和合并文件内容到当前的页面. 页面指令(Page directive):用来定义JSP页面中特定 ...