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 等类型,解决方案:

  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);

三、总结

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

原文地址:https://www.cnblogs.com/sgoldl/p/9713726.html

时间: 2024-10-16 20:26:47

JS数组专题2?? ? 数组去重的相关文章

JS求多个数组的重复数据

今天朋友问了我这个问题:JS求多个数组的重复数据 注: 1.更准确的说是只要多个数组中有两个以上的重复数据,那么这个数据就是我需要的 2.单个数组内的数据不存在重复值(当然如果有的话,你可以去重) 3.耗时问题,这一点很重要 源代码: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>获取多个数组中

JS的二维数组

今天,记录一下JS的二位数组,并附上例题. 一.二维数组的本质:数组中的元素又是数组. 其实,我们都见过这样的二维数组,只不过没在意罢了,例如: var arr = [[1,2,4,6],[2,4,7,8],[8,9,10,11],[9,12,13,15]] //这就是一个二位数组arr[2][3]; // 11 注意:表示第三列第4行所在的元素.角标从0开始 二.下面介绍二维数组的初始化 记住了二维数组的本质,初始化也难不倒我们了.看一下实例 实例一: var arr = [[1,2],[a,

js 的数组怎么push一个对象. Js数组的操作push,pop,shift,unshift JavaScript使用push方法添加一个元素到数组末 JavaScript数组函数unshift、shift、pop、push使用

push()函数用于向当前数组的添加一个或多个元素,并返回新的数组长度.新的元素将会依次添加到数组的末尾. 该函数属于Array对象,所有主流浏览器均支持该函数. 语法 array.push( item1 [,items... ] )参数 参数 描述item1 任意类型添加到当前数组末尾处的元素.items 可选参数/任意类型要添加到当前数组末尾处的其他项,可以有多个.注意:如果添加的元素类型为数组类型(Array),仍然会被当作一个元素看待,只是这个元素是数组类型而已.如果要合并两个数组,请使

js连接多个数组并删除重复的元素

js连接多个数组并删除重复的元素:在实际应用中,可能需要将多个数组合并到一个数组中去,并且删除数组中重复的元素.代码实例如下: var a=["antzone","蚂蚁部落","市南区"], b=["新锐科技","蚂蚁部落","努力奋斗"], c=[2,"新锐科技","js教程"], _a=a.concat(b).concat(c), _hash=

js 如何动态添加数组_百度知道

1.数组的创建var arrayObj = new Array(); //创建一个数组var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限,是长度var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]); 创建一个数组并赋值 要说明的是,虽然第二种方法创建数组指定了长度,但实际上所有情况下数组都是变长的,也就是说即使指定了长度为5,仍然可以将元素存储在规定长度以外

js之二维数组定义和初始化三种方法

方法一:直接定义并且初始化,这种遇到数量少的情况可以用 var _TheArray = [["0-1","0-2"],["1-1","1-2"],["2-1","2-2"]] 方法二:未知长度的二维数组 var tArray = new Array();   //先声明一维 for(var k=0;k<i;k++){        //一维长度为i,i为变量,可以根据实际情况改变

js如何移除数组中指定索引的项

js如何移除数组中指定索引的项:在Array对象中有给定的函数可以删除数组中指定的元素,虽然非常好用,但是总感觉看不到摸不着的比较别扭,下面就分享一个自定义的删除数组指定索引值元素的函数,希望给大家一个全新的思路.代码实例如下: var array=[]; array[0]="蚂蚁部落一"; array[1]="蚂蚁部落二"; array[2]="蚂蚁部落三"; array[3]="蚂蚁部落四"; array[4]="

探讨JS合并两个数组的方法

我们在项目过程中,有时候会遇到需要将两个数组合并成为一个的情况. 比如: 1 2 var a = [1,2,3]; var b = [4,5,6]; 有两个数组a.b,需求是将两个数组合并成一个.方法如下: 1.concat js的Array对象提供了一个叫concat()方法,连接两个或更多的数组,并返回结果. 1 var c = a.concat(b);//c=[1,2,3,4,5,6] 这里有一个问题,concat方法连接a.b两个数组后,a.b两个数组的数据不变,同时会返回一个新的数组.

js数组对象以及数组常用属性和方法

定义形式: var  arr1 = new Array(1,  5,  8,  7,  2,  10);  //定义了一个数组,其中具有6个数据 var  arr2 = new Array();                   //只是单纯地定义了一个数组(名),但没有给值(数据),即现在是空的 var  arr3 = [1,  5,  8,  7,  2,  10];  //同arr1,只是一种简写的定义法. var  arr4 = [ ];                  //同arr