前端宝典二十三:Array最常用的34个方法

news/2024/9/18 20:47:48/ 标签: 前端, 算法

这里列举了Array最常用的34个方法
其中静态方法两个、实例方法32个,对他们进行了分类比较,有助于更好的掌握。

一、前言:手写一个深拷贝

以下是一个用 JavaScript 手写的深拷贝方法,考虑了正则表达式、日期对象、数组和普通对象:

function deepCopy(obj) {if (obj === null || typeof obj!== 'object') {return obj;}let copy;if (Array.isArray(obj)) {copy = [];for (let i = 0; i < obj.length; i++) {copy[i] = deepCopy(obj[i]);}} else if (obj instanceof Date) {copy = new Date(obj);} else if (obj instanceof RegExp) {copy = new RegExp(obj.source, obj.flags);} else {copy = {};for (let key in obj) {if (obj.hasOwnProperty(key)) {copy[key] = deepCopy(obj[key]);}}}return copy;
}

使用示例:

const original = {number: 42,string: 'hello',date: new Date(),regex: /abc/g,array: [1, 2, { nested: 'value' }],object: { key: 'value' }
};const copied = deepCopy(original);console.log(copied);

这里要注意的是

  1. 通过obj instanceof Date判断是不是日期格式,如果是的话使用new Date(obj)
  2. 通过obj instanceof RegExp判断是不是正则格式,如果是的话使用new RegExp(obj.source, obj.flags),这里涉及到了正则的知识点。

这个函数通过判断输入对象的类型,分别处理不同的情况,确保能够正确地深拷贝各种类型的数据。

二、Array静态方法

1、Array.from

静态方法从可迭代或类数组对象创建一个新的浅拷贝的数组实例。

let arr = Array.from('foo');
console.log(arr);
// ["f", "o", "o"]let lst = [1,2,3,{a: 1}];
let newList = Array.from(lst);
newList[3].a = 2;
console.log(newList);
console.log(lst);
// [ 1, 2, 3, { a: 2 } ]
// [ 1, 2, 3, { a: 2 } ]console.log(Array.from([1, 2, 3], (x) => x + x));
// [2, 4, 6]

2、Array.of

通过可变数量的参数创建一个新的 Array 实例,而不考虑参数的数量或类型。

console.log(Array.of('foo', 2, 'bar', true));
// [ 'foo', 2, 'bar', true ]

三、Array实例方法

Array.prototype._
可以在实例对象中使用的方法

1、at( )方法

接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。

let arr1 = [1,2,3,4,5];
let num = arr1.at(-1);
console.log(num);
// 5

2、concat( ) 方法

用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

let arr1 = [1,2,3,4,5];
let arr2 = [6,7,8];
let newArr = arr1.concat(arr2);
console.log(newArr);
console.log(arr1)
[1, 2, 3, 4,5, 6, 7, 8
]
[ 1, 2, 3, 4, 5 ]

3、copyWithin(atrget, start, end) 方法

浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度

  • target:序列开始替换的目标位置
  • start 可选:要复制的元素序列的起始位置
  • end 可选:要复制的元素序列的结束位置,但不包括
console.log([1, 2, 3, 4, 5].copyWithin(0, 2));
// [ 3, 4, 3, 4, 5 ]

同样下面代码可以相同输出

console.log([1, 2, 3, 4, 5].copyWithin(0, 2, 4));
// [ 3, 4, 3, 4, 5 ]

因为end忽略的话,默认从start到数组结尾都被复制

4、entries()方法

返回一个新的数组迭代器对象,该对象包含数组中每个索引的键/值对。

const array1 = ['a', 'b', 'c'];
const iterator1 = array1.entries();
console.log(iterator1.next().value);
console.log(iterator1.next().value);
console.log(iterator1.next().value);
console.log(iterator1.next().value);
//[ 0, 'a' ]
//[ 1, 'b' ]
//[ 2, 'c' ]
//undefined

由于返回一个数组迭代器对象,所以可以被遍历

const a = ["a", "b", "c"];for (const [index, element] of a.entries()) {console.log(index, element);
}// 0 'a'
// 1 'b'
// 2 'c'

接下来是几个遍历的方法了。

5、every() 方法

测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值

const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every((x => x < 40)));
// true

6、filter() 方法

创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。

const words = ['spray', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter((word) => word.length > 6);
console.log(result);
// ["exuberant", "destruction", "present"]

7、forEach() 方法

对数组的每个元素执行一次给定的函数,这个最常用

const array1 = ['a', 'b', 'c'];array1.forEach((element) => console.log(element));// Expected output: "a"
// Expected output: "b"
// Expected output: "c"

8、map() 方法

创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

const array1 = [1, 4, 9, 16];
// Pass a function to map
const map1 = array1.map((x) => x * 2);
console.log(map1);
// [2, 8, 18, 32]

9、some() 方法

测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true,则返回 true;否则返回 false。它不会修改数组。

const array1 = [1, 30, 39, 29, 10, 13];
let res = array1.some((x => x%2 === 0));
console.log(res);

几个遍历方法的end

10、fill() 方法

用一个固定值填充一个数组中从起始索引(默认为 0)到终止索引(默认为 array.length)内的全部元素。它返回修改后的数组。

const array1 = [1, 2, 3, 4];// Fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// [1, 2, 0, 0]// Fill with 5 from position 1
console.log(array1.fill(5, 1));
// [1, 5, 5, 5]console.log(array1.fill(6));
// [6, 6, 6, 6]

11、find() 方法

返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

const array1 = [5, 12, 8, 130, 44];const found = array1.find((element) => element > 10);console.log(found);
// 12

12、findLast() 方法

反向迭代数组,并返回满足提供的测试函数的第一个元素的值。如果没有找到对应元素,则返回 undefined。

13、findIndex() 方法

返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1。

const array1 = [5, 12, 8, 130, 44];const found = array1.findIndex((element) => element > 10);console.log(found);
// 1

14、findLastIndex() 方法

反向迭代数组,并返回满足所提供的测试函数的第一个元素的索引。若没有找到对应元素,则返回 -1。

15、flat() 方法

创建一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。
可以传参,表示打平几次,如果不确定有几层,需要全打平,参数使用Infinity

const arr1 = [0, 1, 2, [3, 4]];console.log(arr1.flat());
// [0, 1, 2, 3, 4]const arr2 = [0, 1, [2, [3, [4, 5]]]];console.log(arr2.flat());
// [0, 1, 2, Array [3, Array [4, 5]]]console.log(arr2.flat(2));
// [0, 1, 2, 3, Array [4, 5]]console.log(arr2.flat(Infinity));
// [0, 1, 2, 3, 4, 5]

16、flatMap() 方法

对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。它等价于在调用 map() 方法后再调用深度为 1 的 flat() 方法(arr.map(…args).flat()),但比分别调用这两个方法稍微更高效一些。

const arr1 = [1, 2, 1];
const result = arr1.flatMap((num) => (num === 2 ? [2, 2] : 1));
console.log(result);
// [1, 2, 2, 1]

上面对数组中的2进行替换为[2, 2]并打平放进去了

const array1 = [1, 2, 1, 2];
const result = array1.flatMap((num) => (num === 2 ? [2, 2] : 1));
console.log(result);
//[ 1, 2, 2, 1, 2, 2 ]

17、includes() 方法

用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。

const array1 = [1, 2, 3];console.log(array1.includes(2));
// trueconst pets = ['cat', 'dog', 'bat'];console.log(pets.includes('cat'));
// trueconsole.log(pets.includes('at'));
// false

18、join() 方法

将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符字符串分隔。如果数组只有一个元素,那么将返回该元素而不使用分隔符。

const elements = ['Fire', 'Air', 'Water'];console.log(elements.join());
//  "Fire,Air,Water"console.log(elements.join(''));
//  "FireAirWater"console.log(elements.join('-'));
// "Fire-Air-Water"

如果没有给定分隔符,会默认使用‘,’如上面代码的第一个
这个方法和String里的split()方法相互互换:

const array1 = [1, 2, 1, 2];
let str = array1.join('');
console.log(str);
let arrs = str.split('');
console.log(arrs);
//1212
//[ '1', '2', '1', '2' ]

19、keys() 方法

返回一个新的数组迭代器对象,其中包含数组中每个索引的键。

const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();for (const key of iterator) {console.log(key);
}// 0
// 1
// 2

20、values() 方法

返回一个新的数组迭代器对象,该对象迭代数组中每个元素的值。这个方法和第19的keys()刚好对应

const array1 = ['a', 'b', 'c'];
const iterator = array1.values();for (const value of iterator) {console.log(value);
}// "a"
// "b"
// "c"

21、push() 方法

将指定的元素添加到数组的末尾,并返回新的数组长度

const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count);
// 4
console.log(animals);
// ["pigs", "goats", "sheep", "cows"]

22、pop() 方法

从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。

const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];console.log(plants.pop());
//  "tomato"console.log(plants);
// ["broccoli", "cauliflower", "cabbage", "kale"]plants.pop();console.log(plants);
// ["broccoli", "cauliflower", "cabbage"]

23、shift() 方法

从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

const array1 = [1, 2, 3];const firstElement = array1.shift();console.log(array1);
// [2, 3]console.log(firstElement);
// 1

24、unshift() 方法

将指定元素添加到数组的开头,并返回数组的新长度

const array1 = [1, 2, 3];console.log(array1.unshift(4, 5));
// 5console.log(array1);
// [4, 5, 1, 2, 3]

以上四个方法,添加新元素的返回长度,删除元素的都是返回该元素。

25、reduce() 方法

对数组中的每个元素按序执行一个提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

const array1 = [1, 2, 3, 4];// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce((accumulator, currentValue) => accumulator + currentValue,initialValue,
);console.log(sumWithInitial);
// Expected output: 10

上面代码中传入了初始值initialValue = 0,如果不传结果也一样,因为默认是从列表第一个元素开始作为初始值

26、reverse() 方法

就地反转数组中的元素,并返回同一数组的引用。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。换句话说,数组中的元素顺序将被翻转,变为与之前相反的方向。

const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);
// ["one", "two", "three"]const reversed = array1.reverse();
console.log('reversed:', reversed);
// ["three", "two", "one"]console.log('array1:', array1);
// ["three", "two", "one"]

Careful: reverse is destructive – it changes the original array. 这个方法是修改原数组的
如果想不修改原数组而去翻转,请用下面的方法

27、toReversed() 方法

是 reverse() 方法对应的复制版本。它返回一个元素顺序相反的新数组。

const items = [1, 2, 3];
console.log(items); // [1, 2, 3]const reversedItems = items.toReversed();
console.log(reversedItems); // [3, 2, 1]
console.log(items); // [1, 2, 3]

28、sort() 方法

就地对数组的元素进行排序,并返回对相同数组的引用。默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序。

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// ["Dec", "Feb", "Jan", "March"]const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// [1, 100000, 21, 30, 4]

这个方法是改变原数组的,如果想不改变原数组排序,请用下面的方法:

29、 toSorted() 方法

是 sort() 方法的复制方法版本。它返回一个新数组,其元素按升序排列。

const months = ["Mar", "Jan", "Feb", "Dec"];
const sortedMonths = months.toSorted();
console.log(sortedMonths); // ['Dec', 'Feb', 'Jan', 'Mar']
console.log(months); // ['Mar', 'Jan', 'Feb', 'Dec']const values = [1, 10, 21, 2];
const sortedValues = values.toSorted((a, b) => a - b);
console.log(sortedValues); // [1, 2, 10, 21]
console.log(values); // [1, 10, 21, 2]

30、slice() 方法

返回一个新的数组对象,这一对象是一个由 start 和 end 决定的原数组的浅拷贝(包括 start,不包括 end),其中 start 和 end 代表了数组元素的索引。原始数组不会被改变。

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];console.log(animals.slice(2));
// ["camel", "duck", "elephant"]console.log(animals.slice(2, 4));
// ["camel", "duck"]console.log(animals.slice(1, 5));
// ["bison", "camel", "duck", "elephant"]console.log(animals.slice(-2));
// ["duck", "elephant"]console.log(animals.slice(2, -1));
// ["camel", "duck"]console.log(animals.slice());
// ["ant", "bison", "camel", "duck", "elephant"]

31、splice() 方法

就地移除或者替换已存在的元素和/或添加新的元素。

const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// Inserts at index 1
console.log(months);
// ["Jan", "Feb", "March", "April", "June"]months.splice(4, 1, 'May');
// Replaces 1 element at index 4
console.log(months);
// ["Jan", "Feb", "March", "April", "May"]

32、 with() 方法

是使用方括号表示法修改指定索引值的复制方法版本。它会返回一个新数组,其指定索引处的值会被新值替换。

const arr = [1, 2, 3, 4, 5];
console.log(arr.with(2, 6)); // [1, 2, 6, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5]

http://www.ppmy.cn/news/1518747.html

相关文章

12 对话模型微调2

1 P-Tuning P-Tuning 是在 Prompt-Tuning的基础上&#xff0c;通过新增 LSTM 或 MLP 编码模块来加速模型的收敛&#xff1b; 之前的实验也看到了使用prompt训练速度很慢&#xff0c;那么P-Tuning呢 参数占比&#xff1a; trainable params: 5,267,456 || all params: 1,308,37…

Windows服务器应急响应(下)

目录 介绍步骤 介绍 进程&#xff08;Process&#xff09;是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础。在早期面向进程设计的计算机结构中&#xff0c;进程是程序的基本执行实体&#x…

sql 优化,提高查询速度

文章目录 一、前言二、建议2.1 使用索引2.2 避免使用select *2.3. 使用表连接代替子查询2.4. 优化WHERE子句&#xff0c;减少返回结果集的大小2.5 用union all代替union2.6 使用合适的聚合策略2.7 避免在WHERE子句中使用函数2.8 使用EXPLAIN分析查询2.9 小表驱动大表2.10 使用窗…

PHP程序设计教案

文章目录&#xff1a; 一&#xff1a;前言 1.什么是PHP 2.环境安装 3. 语法规范 3.1 注释 3.2 分隔符 3.3 其他规范 二&#xff1a;基础语法 1.输出 1.1 echo 1.2 print 1.3 var_dump类型和值 1.4 print_r()易读 2.常量变量 2.1 常量 2.1.1 define()/const…

vue前端实现登录页面的验证码(新手版)

一、搭建vue前端登录页面 <template><div style"width: 800px; margin: 5px auto; background-color: #17ecf3"><div align"center"><h2>用户登录</h2></div><div style"width: 60%; margin: 1px auto"…

如何解决`.gitignore`规则不生效或已提交相关文件的问题

前言 在使用Git进行版本控制时&#xff0c;.gitignore文件是一个非常有用的工具&#xff0c;它可以帮助我们排除不需要跟踪的文件或目录。然而&#xff0c;在实际开发过程中&#xff0c;有时我们会遇到.gitignore规则不生效的情况&#xff0c;或者是不小心将不应提交的文件提交…

RabbitMQ 入门教程

RabbitMQ 入门教程 1. 引言 RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;实现高级消息队列协议 (AMQP)。它能帮助开发者实现应用程序间的解耦、异步处理、流量削峰等需求。 2. 安装与配置 2.1 安装RabbitMQ 2.1.1 Ubuntu bash sudo apt-get update sudo apt…

动态IP池在数据抓取中的应用与优势

随着互联网技术的快速发展&#xff0c;数据抓取&#xff08;Web Scraping&#xff09;已经成为获取互联网信息的重要手段。然而&#xff0c;在进行大规模数据抓取时&#xff0c;往往会遇到反爬虫机制、IP封禁等问题。动态IP池作为一种解决方案&#xff0c;可以有效地绕过这些障…

告别手动记录,音频转文字软件助力会议记录新高度

如果你突然被领导指派去参与一场会议&#xff0c;身边没有纸笔要怎么记录转达会议内容呢&#xff1f;我往往会采用手机的录音功能来记录会议内容会后再进行整理。这次我们就来探索音频转文字工具怎么提升我们的工作效率。 1.365在线转文字 链接传送&#xff1a;https://www.p…

微服务优缺点以及如何拆分

微服务优点 1,降低代码逻辑复杂度。 单个微服务模块相当于一个项目&#xff0c;开发人员只用关心这个模块的逻辑即可。 2&#xff0c;技术栈更加灵活 不同的微服务可以使用合适的语言架构实现&#xff0c;然后把服务注册到一个注册中心即可相互调用。 3&#xff0c;按需伸缩 当…

人工智能工作级开发者认证 HCCDP – AI 真题2 答案

1.GBDT通过bagging的防范可以对样本和特征都进行采集。答案:FALSE 原因:GBDT可以对样本采集,不能对特征采集 2.深度学习是机器学习的一个分支。答案:true 3.softmax激活函数的作用是减少及时量和防止梯度消失。答案false 4.在建筑施工现场,基于定制化的图像识别目标检测系统,…

Node.js 安装与使用及连接 MongoDB 的详细教程

下面我将详细讲解如何安装 Node.js、介绍 Node.js 的脚手架工具、使用 Express 脚手架创建项目&#xff0c;以及如何安装和连接 MongoDB。 一、Node.js 安装 下载 Node.js&#xff1a; 访问 Node.js 官方网站。 根据你的操作系统选择最新的 LTS&#xff08;长期支持版&#x…

从自动驾驶看无人驾驶叉车的技术落地和应用

摘 要 &#xff5c; 介绍无人驾驶叉车在自动驾驶技术中的应用&#xff0c;分析其关键技术&#xff0c;如环境感知、定位、路径规划等&#xff0c;并讨论机器学习算法和强化学习算法的应用以提高无人叉车的运行效率和准确性。无人叉车在封闭结构化环境、机器学习、有效数据集等方…

参加 帆软 BI 上海城市 课堂(08-30培训)

参加 帆软 BI 城市 课堂&#xff08;0830&#xff09;&#xff1a; 由于目前是自由职业&#xff0c;也想学习一下新的知识 。所以参加本次的培训&#xff0c;总的来说还是比较专业。 培训在 上海 帆软的总部 环球港进行。时间是 13:30~17&#xff1a;00 老师很专业。学习中 课…

关于前端布局的基础知识

float 横向布局 float 实现横向布局&#xff0c;需要向横着布局的元素添加float 其值left right 存在问题 如果使用float 所在父级五高度&#xff0c;会导致下方的元素上移 top的高度被吞了 解决方法&#xff1a; 给父级元素设置高度&#xff1a;不推荐&#xff0c;需要给父级…

LeetCode第65题 有效数字 结合设计模式:状态模式

思路&#xff1a;有限状态机&#xff0c;结合Java的设计模式&#xff1a;状态模式。 单纯用状态机会有大量的if-else&#xff0c;非常不好看&#xff0c;思路不清晰 用设计模式则非常清楚。但是设计模式是为了给人理解的&#xff0c;对机器而言也可能稍微影响性能&#xff1b; …

IO练习--随机点名

随机点名器1 需求: 有一个文件里面存储了班级同学的信息&#xff0c;每一个信息占一行。 格式为:张三-男-23 要求通过程序实现随机点名器。 运行效果: 第一次运行程序:随机同学姓名1(只显示名字) 第二次运行程序:随机同学姓名2(只显示名字) 第三次运行程序:随机同学姓名3(只显…

【精选】基于Hadoop的用户网站浏览分析的设计与实现(全网最新定制,独一无二)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

2.10鼠标事件

目录 实验原理 实验代码 运行结果 文章参考 实验原理 在 OpenCV 中存在鼠标的操作&#xff0c;比如左键单击、双击等。对于 OpenCV 来讲&#xff0c;用户的鼠标操作被认为发生了一个鼠标事件&#xff0c;需要对这个鼠标事件进行处理&#xff0c;这就是事件的响应。下面我们…

软件设计原则之接口隔离原则

接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09;是面向对象设计中的一个重要原则&#xff0c;它属于SOLID原则之一。这个原则强调客户端&#xff08;即接口的调用者&#xff09;不应该被迫依赖于它们不使用的方法。换句话说&#xff0c;一个类对另一…