JS数组专题2️⃣ ➖ 数组去重
距离上次发文,已经有一段时间了,最近工作比较忙,这不眼看快双十一了,就相当于给大家一些福利吧!
一、什么是数组去重
简单说就是把数组中重复的项删除掉,你 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等类型,解决方案:
- 添加判断数据类型,比如
typeof,obj[typeof arr[i] + arr[i]]不过这还是判断不了['1']和[1],因为这被相加后,结果都一样- 添加
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️⃣ ➖ 数组去重的更多相关文章
- JS数组专题1️⃣ ➖ 数组扁平化
一.什么是数组扁平化 扁平化,顾名思义就是减少复杂性装饰,使其事物本身更简洁.简单,突出主题. 数组扁平化,对着上面意思套也知道了,就是将一个复杂的嵌套多层的数组,一层一层的转化为层级较少或者只有一层 ...
- LeetCode:数组专题
数组专题 有关数组的一些 leetcode 题,在此做一些记录,不然没几天就忘光光了 二分查找 双指针 滑动窗口 前缀和/差分数组 二分查找 本文内容摘录自公众号labuladong中有关二分查找的文 ...
- js面试题之数组去重对比
最近看一些面试题,很多都提到了数组去重,用的最多的不外乎就是下面这个例子 arr.filter(function(value,index,arr){ return arr.indexOf(value, ...
- 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)
目录 这是<前端总结·基础篇·JS>系列的第二篇,主要总结一下JS数组的使用.技巧以及常用方法. 一.数组使用 1.1 定义数组 1.2 使用数组 1.3 类型检测 二.常用技巧 2.1 ...
- JS 使用 splice() 对数组去重
一 问题 有如下 js 数组 connect_clients,需要在去掉所有元素中 user_id, goods_id 这两者的值都相同的元素. [ { id: 'eff040fb-92bc-4f24 ...
- JS 两个对象数组合并并去重
JS两个对象数组合并并去重 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- JS如何去掉一个数组的重复元素 (数组去重)
一.思路如下: 定义一个新数组,将老数组遍历一遍,再进行判断,如果新数组里面没有老数组的元素就添加,否则就不添加,最终输出整个新数组. 二.代码如下: var arr = ["a" ...
- 亲测有效JS中9种数组去重方法
码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14555831.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...
- js array.filter实例(数组去重)
语法: 循环对数组中的元素调用callback函数, 如果返回true 保留,如果返回false 过滤掉, 返回新数组,老数组不变 var new_array = source_array.filt ...
随机推荐
- java多线程中用到的方法详细解析
在多线程学习的过程中涉及的方法和接口特别多,本文就详细讲解下经常使用方法的作用和使用场景. 1.sleep()方法. 当线程对象调用sleep(time)方法后,当前线程会等待指定的时间(t ...
- 编译出现No rule to make target `out/host/linux-x86/bin/aapt', needed by `out/target/common/obj/APPS/MyTv4_intermediates/src/R.stamp'问题
查找路径发现的确没有MyTv4_intermediates/src/R.stamp,这需要生成这个文件
- iOS 更改状态栏、导航栏颜色的几种方法
ios上状态栏 就是指的最上面的20像素高的部分状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池.时间等部分:背景部分:就是显示黑色或者图片的背景部分: (一)设置sta ...
- Qt 进程和线程之一:运行一个进程和进程间通信
Qt提供了对进程和线程的支持.本节讲述了怎样在Qt应用程序中启动一个进程,以及几种常用的进程间通信方法.如果对进程和线程的概念不是很了解,可以看我的另一篇博客:[多进程和多线程的概念. 设计应用程序时 ...
- [WOJ4354] 蜀石经
题目链接: 点我 题目分析: 大模拟,貌似\(O(n^2)\)也可以卡常过,复杂度正确的做法是用优先队列维护. 代码: #include<bits/stdc++.h> #define N ...
- Python开发 第01课 Python 简介
一.Python 介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为AB ...
- 转 SecureCRT中文乱码解决方法
1. 打开对话窗口,在工具栏中点开“选项”,选择“会话选项”. 2. 在打开的“会话选项”中,选择“外观”. 3. 在显示的“窗口和文本外观”中找到“字符编码”. 4. 把“字符编码”设置为“U ...
- Crusher Django 学习笔记2 基本url配置
http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial2-conf-basic-url.html 顺便学习一下FQ Cr ...
- 本地连接远程Oracle数据库
由于项目开发测试,需要在本地连接远程的Oracle数据库 之前搭过环境,但是重装了系统,现在又重新装一遍 软件安装 连接远程Oracle需要两个软件: 一个Oracle客户端,instantclien ...
- 物体检测丨Faster R-CNN详解
这篇文章把Faster R-CNN的原理和实现阐述得非常清楚,于是我在读的时候顺便把他翻译成了中文,如果有错误的地方请大家指出. 原文:http://www.telesens.co/2018/03/1 ...