当前位置: 首页 > news >正文

JS中数组如何去重(ES6新增的Set集合类型)+经典two sum面试题

现在有这么一个重复数组:

const arr = ['a','a','b','a','b','c']

只推荐简单高效的方法,复杂繁琐的方法不做推荐

方法一:

const res = [...new Set(arr)]

Set类型是什么呢?

Set 是ES6新增的一种新集合类型具体知识点可以看下面附录:

根据上面的知识点,我们可以得到:

console.log(...new Set(arr)) // a b c

所以去重也可以这么实现:

const res = Array.from(new Set(arr)) // Array.from将类数组转换成数组
// or
const res = Array.of(...new Set(arr)) // Array.of根据传入的参数生成数组

方法二:

var arr = ['apple','apps','pear','apple','orange','apps'];  
var newArr = arr.filter(function(item,index){return arr.indexOf(item) === index;  // 因为indexOf 只能查找到第一个  
});

方法三:

some + 循环去重

function distinct(list) {let result = [list[0]];// 用于承接没有重复的数据,初始时将原始数组的第一个值赋给它。for (let i = 1; i < list.length; i++) {// 判断结果数组中是否存在一样的值,若果没有的话则将数据存入结果数组中。if (!(result.some(val => list[i] === val))) {result.push(list[i]);}}return result;}

方法四:

如果不能用ES6、5的语法。需要原生方法双重for循环去重:

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

方法五:

简单数组用includes去重

function noRepeat(arr) {let newArr = [];for(i=0; i<arr.length; i++){if(!newArr.includes(arr[i])){newArr.push(arr[i])}}return newArr
}

附录 -Set

使用 new 关键字和 Set 构造函数可以创建一个空集合:

const s = new Set();

如果想在创建的同时初始化实例,则可以给 Set 构造函数传入一个可迭代对象(Array Map Set WeakMap WeakSet)。可迭代对象需要包含插入到新集合实例中的元素(Set 可以包含任何 JavaScript 数据类型作为值)。Set构造函数会迭代传入参数,去重后保存到集合实例中。

特点

  1. Set 是唯一值的集合。

  1. 每个值在 Set 中只能出现一次。

  1. 一个 Set 可以容纳任何数据类型的任何值。

你可以把Set想像成跟数组一样,我们用size来输出Set集合的长度。

const s = new Set(['a','b','c','c']);
s.size; // 3 去重了一个c
const s2 = new Set();
s2.add('a')
s2.add('b')
s2.add('c')
s2.size // 3

与Array的区别

最根本的区别是数组是一个索引集合,这说明数组中的数据值按索引排序。

相比之下,set是一个键的集合。set不使用索引,而是使用键对数据排序(看下面forEach)。set 中的元素按插入顺序是可迭代的,它不能包含任何重复的数据。

对比Array的优势

在运行时间方面上Set占了很大的优势

  • 查看元素:使用indexOf()或includes()检查数组中的项是否存在是比较慢的。

  • 删除元素:在Set中,可以根据每项的的 value 来删除该项。在数组中,等价的方法是使用基于元素的索引的splice()。与前一点一样,依赖于索引的速度很慢。

  • 保存 NaN:不能使用indexOf()或 includes() 来查找值 NaN,而 Set 可以保存此值。

  • 删除重复项:Set对象只存储惟一的值,如果不想有重复项存在,相对于数组的一个显著优势,因为数组需要额外的代码来处理重复。

时间复杂度:
数组用来搜索元素的方法时间复杂度为0(N)。换句话说,运行时间的增长速度与数据大小的增长速度相同。
相比之下,Set用于搜索、删除和插入元素的方法的时间复杂度都只有O(1),这意味着数据的大小实际上与这些方法的运行时间无关。

具体解释与面试题强烈推荐阅读如何使用 Set 来提高JS代码的性能 - 知乎 (zhihu.com)

其他API

has()

查询Set实例是否存在某元素(返回布尔值):

const s = new Set();
s.add(1).add(2).add(3);
s.has(1); // true
delete()

删除某个元素

s.delete(1);
clear()

清空Set实例

s.clear();
Array.from(s); // []

迭代:

for of

for in不输出,因为它不是以下标为索引的集合

const s = new Set(['a','b','c','c']);
for (var n of s) {console.log(n)}
// a
// b
// c
forEach
s.forEach((t,i)=>console.log(t,i))
// a a
// b b
// c c
// 输出了键值对的结构
原生属性

可以看见Set实例的三个属性返回了枚举的类数组。

直接用Array.form转换

Array.from(s.keys())
// ['a', 'b', 'c']
Array.from(s.entries())
// [['a', 'a'],['b', 'b'],['c', 'c']]
Array.from(s.values())
// ['a', 'b', 'c']

附录-面试题

题目:

给定一个整数无序数组和变量 sum,如果存在数组中任意两项和使等于 sum 的值,则返回true。否则,返回false。例如,数组[3,5,1,4]和 sum = 9,函数应该返回true,因为4 + 5 = 9。

解题思路:

本题其实是为了找数组元素与sum的差值是否在数组里重复出现。

const s = new Set()
arr.some(t=> {if (s.has(t)) {return true}s.add(sum-t);return fasle
})

简洁点写:

const findSum = (arr, sum) =>arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));

http://www.lryc.cn/news/15735.html

相关文章:

  • HDLC简介及相应hdlc实训
  • 公司技术团队为什么选择使用 YApi 作为 Api 管理平台?
  • ts知识点整理
  • 技术分享 | OceanBase 数据处理之控制文件
  • TCP的三次握手、四次挥手
  • C++---特殊类的设计
  • buu [WUSTCTF2020]dp_leaking_1s_very_d@angerous 1
  • 基于SVPWM改进的永磁同步电机直接转矩控制二更
  • ubuntu下磁盘管理
  • Python学习-----排序问题1.0(冒泡排序、选择排序、插入排序)
  • LeetCode 535. TinyURL 的加密与解密
  • 【c++】类和对象2—构造函数、析构函数、拷贝构造函数
  • [C++关键字] const/constexpr
  • FPGA电源电流参数
  • 【Git】Git下载安装与使用(一)
  • 刷题记录:牛客NC20545[HEOI2012]采花
  • 每日学术速递2.21
  • 网络安全之认识挖矿木马
  • OpenCV实战——基于分水岭算法的图像分割
  • YOLOv8模型调试记录
  • 算法刷题打卡第97天:删除字符串两端相同字符后的最短长度
  • WebGPU学习(3)---使用IndexBuffer(索引缓冲区)
  • Java代码加密混淆工具有哪些?
  • 华为OD机试 - 高效的任务规划(Python) | 机试题+算法思路+考点+代码解析 【2023】
  • ChatGPT写程序如何?
  • 编译链接实战(9)elf符号表
  • React合成事件的原理是什么
  • Arduino-交通灯
  • 【论文笔记】Manhattan-SDF == ZJU == CVPR‘2022 Oral
  • 好消息!Ellab(易来博)官方微信公众号开通了!携虹科提供专业验证和监测解决方案