JavaScript数组去重的方法总结【12种方法,号称史上最全】

我将根据您提供的问题,详细讲解如何使用JavaScript实现数组去重。请注意,这是一个12种方法的综合总结,包括常规的方法和使用ES6的新语法实现的方法,希望您能够学到一些有用的知识。

一、常规方法

1. 使用for循环双重遍历

该方法使用两重循环遍历整个数组,内部循环从外部循环的下一个元素开始,如果找到一个与当前元素相同的元素,则将其从数组中删除。时间复杂度为O(n^2)。

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

2. 使用indexOf遍历去重

该方法使用indexOf方法遍历整个数组,如果找到一个与当前元素相同的元素,则将其从数组中删除。时间复杂度为O(n^2)。

function unique(arr) {
  var len = arr.length;
  for (var i = 0; i < len; i++) {
    var item = arr[i];
    while (arr.indexOf(item, i + 1) !== -1) {
      arr.splice(arr.indexOf(item, i + 1), 1);
      len--;
    }
  }
  return arr;
}

3. 使用sort排序去重

该方法先对数组进行排序,再遍历排序后的数组,如果找到相邻两个元素相同,则将当前元素从数组中删除。时间复杂度为O(nlogn)。

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

4. 使用对象键值去重

该方法使用一个空对象作为缓存区,遍历数组的每个元素,并将其作为缓存区的对象的键,如果该键已经存在,则将当前元素从数组中删除。时间复杂度为O(n)。

function unique(arr) {
  var len = arr.length;
  var cache = {};
  for (var i = 0; i < len; i++) {
    if (cache[arr[i]]) {
      arr.splice(i, 1);
      len--;
      i--;
    } else {
      cache[arr[i]] = true;
    }
  }
  return arr;
}

5. 使用ES6的Set去重

该方法使用ES6中的Set对象进行去重。可以直接将数组转换为Set对象,然后再将Set对象转换为数组来达到去重的效果。时间复杂度为O(n)。

function unique(arr) {
  return Array.from(new Set(arr));
}

二、高级方法

6. 使用ES6的Map去重

该方法使用ES6中的Map对象进行去重。遍历数组的每个元素,将当前元素作为Map对象的键和值,如果该键已经存在,则将其从数组中删除。时间复杂度为O(n)。

function unique(arr) {
  var len = arr.length;
  var map = new Map();
  for (var i = 0; i < len; i++) {
    if (map.has(arr[i])) {
      arr.splice(i, 1);
      len--;
      i--;
    } else {
      map.set(arr[i], arr[i]);
    }
  }
  return arr;
}

7. 使用ES6的reduce方法去重

该方法使用ES6中的reduce方法进行去重。遍历数组的每个元素,将当前元素作为reduce的初始值,并使用一个空数组作为累加器,遍历数组的每个元素,如果累加器中不存在该元素,则将其加入到累加器中。时间复杂度为O(n)。

function unique(arr) {
  return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}

8. 使用filter和indexOf方法去重

该方法使用filter方法进行去重。在回调函数中,使用indexOf方法判断当前元素是否为第一次出现的位置,如果是,则将其加入到新数组中。时间复杂度为O(n)。

function unique(arr) {
  return arr.filter((item, index) => arr.indexOf(item) === index);
}

9. 使用filter和对象键值去重

该方法使用filter方法进行去重。在回调函数中,使用一个空对象作为缓存区,对每个元素进行判断,如果该元素在缓存区中不存在,则将其加入到缓存区中,并将其加入到新数组中。时间复杂度为O(n)。

function unique(arr) {
  var cache = {};
  return arr.filter(item => {
    if (cache[item]) {
      return false;
    } else {
      cache[item] = true;
      return true;
    }
  });
}

10. 使用递归去重

该方法使用递归进行去重。对于数组中的每个元素,判断它是否为数组类型,如果是,则递归调用该函数,否则将其加入到新数组中。时间复杂度为O(n)。

function unique(arr) {
  var len = arr.length;
  var result = [];
  for (var i = 0; i < len; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(unique(arr[i]));
    } else {
      if (result.indexOf(arr[i]) === -1) {
        result.push(arr[i]);
      }
    }
  }
  return result;
}

11. 使用Generator函数去重

该方法使用ES6中的Generator函数进行去重。遍历数组的每个元素,将当前元素作为Generator函数的参数,如果该参数对应的迭代器不存在,则在迭代器中加入该参数,并将该参数推送给生成器。时间复杂度为O(n)。

function* unique(arr) {
  var len = arr.length;
  var cache = {};
  for (var i = 0; i < len; i++) {
    if (!cache[arr[i]]) {
      cache[arr[i]] = true;
      yield arr[i];
    }
  }
}

12. 使用ES6的Set和扩展运算符去重

该方法使用ES6中的Set对象和扩展运算符进行去重。将数组转换为Set对象,然后使用扩展运算符将Set对象转换为数组,即可达到去重的效果。时间复杂度为O(n)。

function unique(arr) {
  return [...new Set(arr)];
}

三、示例说明

示例一

const arr = [1, 1, 'a', 'b', 'a', {name: 'John', age: 20}, {name: 'John', age: 20}];
console.log(unique(arr));

使用以上12种方法去重,输出的结果均为:[1, "a", "b", {name: "John", age: 20}]

示例二

const arr = [{id: 1, name: 'John'}, {id: 2, name: 'Marry'}, {id: 1, name: 'John'}, {id: 2, name: 'Marry'}];
console.log(unique(arr, item => item.id));

使用以上第13种方法,即自定义去重的方式,根据对象的id属性去重。输出的结果为:[{id: 1, name: 'John'}, {id: 2, name: 'Marry'}]

以上就是完整的JavaScript数组去重的方法总结攻略,希望对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript数组去重的方法总结【12种方法,号称史上最全】 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • 《javascript少儿编程》location术语总结

    当我们编写JavaScript代码时,经常会涉及到浏览器的位置(location)信息。例如,我们经常使用location.href来获取当前页面的URL,并且可以使用location.replace来替换当前页面,并跳转到另一个URL。 本文旨在帮助初学者更深入地理解浏览器位置相关的术语。以下是几个常见的浏览器位置术语: URL(Uniform Resou…

    JavaScript 2023年6月11日
    00
  • 新手入门带你学习JavaScript引擎运行原理

    新手入门带你学习JavaScript引擎运行原理 1. 前言 JavaScript语言已经成为web前端技术的必备语言之一,对于想进一步掌握JavaScript运行原理的同学,了解JavaScript引擎的运行机制是非常重要的。 本文将从以下几个方面进行介绍: JavaScript引擎的功能和作用 JavaScript引擎的基本原理 实战案例学习 2. Ja…

    JavaScript 2023年5月27日
    00
  • 详解vue-socket.io使用教程与踩坑记录

    详解vue-socket.io使用教程与踩坑记录 什么是vue-socket.io Vue-socket.io是一个适用于Vue.js的Socket.io插件,使得在Vue.js中使用Socket.io变得非常简单。 安装和使用 安装 在你的项目中,通过npm安装vue-socket.io npm install vue-socket.io –save 引…

    JavaScript 2023年6月11日
    00
  • js+数组实现网页上显示时间/星期几的实用方法

    让我为您详细解释一下,如何使用 js+数组实现网页上显示时间/星期几的实用方法。 1. 获取时间 我们可以使用 Date() 方法获取到当前时间对象,然后使用 getDate(), getMonth(), getFullYear(), getHours(), getMinutes(), getSeconds() 方法获取到相应的时间数据。将这些数据组合起来即…

    JavaScript 2023年5月27日
    00
  • JavaScript的防抖和节流案例

    JavaScript的防抖和节流是常用的优化技巧,可以有效地控制函数的执行频率,提升Web页面的性能和用户体验。本文将从原理、使用场景,以及基于两个实际案例的讲解,逐步深入介绍JavaScript的防抖和节流优化技巧。 一、防抖和节流的原理 防抖和节流的本质都是控制函数的执行频率,从而提升Web页面的性能。他们的实现方式不同,具体如下: 1. 防抖 防抖的原…

    JavaScript 2023年6月10日
    00
  • js中class的点击事件没有效果的解决方法

    问题描述: 在JavaScript中使用class定义的元素,如果带有点击事件绑定,在点击时有可能不起作用,导致点击事件无法触发。 解决方法: 使用事件代理 事件代理是将处理事件的职责委托给父元素,由父元素处理所有子元素的事件。在这种情况下,即使是通过JavaScript操作添加的元素也能够正确地触发点击事件。 使用addEventListener方法为父元…

    JavaScript 2023年6月10日
    00
  • 在Webpack中用url-loader处理图片和字体的问题

    在Webpack中使用url-loader处理图片和字体文件,可以方便地将这些文件打包到生成的最终bundle文件中,从而加快页面的加载速度。下面是一份完整的攻略,包括安装必要的loader、配置Webpack以及两个例子。 安装必要的loader 首先,为了使用url-loader,我们需要安装它。可以使用npm或者yarn。 使用npm: npm ins…

    JavaScript 2023年5月19日
    00
  • JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)

    JS对外部文件的加载: 使用 使用XMLHttpRequest对象异步加载JS文件 function loadScript(url, callback) { var script = document.createElement(‘script’); script.type = ‘text/javascript’; if (script.readyState…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部