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://juejin.im/post/5bac8d1c5188255c672eb870

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值