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

一、什么是数组去重

简单说就是把数组中重复的项删除掉,你 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);

三、总结

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

最新文章

  1. RG100A-AA 中大校园网上网及远程配置
  2. 论文笔记之:Playing for Data: Ground Truth from Computer Games
  3. [转]整理索引碎片,提升SQL Server速度
  4. JAVA TCP/IP Socket通信机制以及应用
  5. Robot Framework语法学习(一)
  6. express4.0之后不会解析req.files,必须加一个插件multer
  7. 获取extjs text列修改过 数据
  8. 改动file header (測)
  9. jQuery全屏插件Textarea Fullscreen
  10. 机器学习算法与实现 之 Logistic Regression---java实现
  11. html标签默认样式整理
  12. spine动画融合与动画叠加
  13. SAXReader简单实例解析HTML
  14. 【ASP.NET】website转webapplication
  15. WAV文件有多大?MP3文件有多大?使用Lame 压缩比是多少?
  16. BugkuCTF sql注入
  17. 阅读程序 回答问题——FindTheNumber
  18. dotnetty 心跳
  19. ios开发之--使用UILabel Category 计算UILabel内容大小
  20. leetcode:Single Number【Python版】

热门文章

  1. IT兄弟连 JavaWeb教程 EL与JSTL表达式经典案例
  2. 记录下java的个人测试方法
  3. 【OpenJ_Bailian - 4005】拼点游戏(贪心)
  4. PostgreSQL-8-数据合并
  5. django_view操作数据库
  6. laravel之null替换空字符串中间件
  7. UVA297:Quadtrees(四分树)
  8. freertos之队列
  9. FXP登录Linux报错
  10. vue使用props动态传值给子组件里的函数用,每次更新,呼叫函数