JS【详解】数组(数组的本质、创建数组、常用数组操作API汇总对比和实战范例、数组的遍历、复制、去重等)

数组用于存储多个有序的数据

  • 数组本质上是以数字为键(从0开始,依次递增),并外加一个会自动增长的 length 属性的对象。

创建数组

方式 1 - 通过字面量创建

// 空数组
let arr1 = [];
let arr2 = [1,2,3];

方式 2 - 使用构造函数 new Array()

let arr1 = new Array(); // 参数为空,得到一个空数组 []
let arr2 = new Array(4); // 参数为一个数值时表示数组的长度,得到  [undefined,undefined,undefined,undefined]
let arr3 = new Array(15, 16, 17); // 参数为多个数值时表示数组中的元素,得到[15,16,17]

方式 3 - Array.of()

ES6 新增语法

let arr = Array.of(1, 'abc', true);

当只有一个参数时,构造函数 Array 会将其作为数组的长度,而不是元素,这很容易造成歧义(因为其他参数数量时,参数都是数组的元素,而不是数组的长度),因此,ES6 新增了 Array.of() 语法来避免这种歧义。

let arr1 = Array.of(2) //[2]
let arr2 = Array.of("2") //["2"]
let arr3 = Array.of(1,"2",{obj: "3"}) //[1,"2",{obj: "3"}]

方式 4 - Array().fill()

用于创建指定数量,元素相同的数组

  • Array 的参数为数字
  • fill 的参数为元素
Array(9).fill('1')

得到

["1", "1", "1", "1", "1", "1", "1", "1", "1"]

常用的数组操作

数组的API功能入参返回值是否改变原数组
unshift在数组头部追加元素新元素数组的新长度改变
push在数组尾部追加元素新元素数组的新长度改变
shift移除数组的第一项被移除的元素改变
pop移除数组最后一项被移除的元素改变
sort数组排序排序规则函数排序后的数组改变
reverse数组反转反转后的数组改变
fill数组覆写新元素,起始下标,终点下标覆写后的数组改变
splice拼接数组下标,删除数量,新元素移除元素的数组改变
slice数组截取起始下标,终点下标截取的数组不改变
filter数组过滤过滤规则函数过滤后的数组不改变
reduce数组缩减缩减规则函数计算结果不改变
toString数组转字符串字符串不改变
join拼接元素拼接符字符串不改变

判断是否为数组 Array.isArray()

let list = [1, 2, 3];
let a = 1;let result1 = Array.isArray(list); // true
let result2 = Array.isArray(a); // false

获取数组的长度 length

let list = [1, 2, 3];
let result = list.length; // 3

修改数组的长度

  • 如果新长度 > 原长度,多出的部分会填充 null。

    let arr2 = [21, 22, 23];
    arr2.length = 5;  // [21,22,23,null,null]
    
  • 如果新长度 < 原长度,多出的元素会被删除

    let arr1 = [11, 12, 13];
    arr1.length = 1;  // [11]
    

访问元素 []

通过数组的下标访问

let list = [1, 2, 3];// 访问数组第一个元素
console.log(list[0]); // 打印结果:1// 访问数组最后一个元素
console.log(list[list.length - 1]); // 打印结果:3// 访问数组不存在的下标
console.log(list[5]); // 打印结果:undefined

搜索元素

查找目标元素的下标 indexOf()

从前往后查找,若数组中存在目标元素,则返回目标元素在数组中的第一个下标,如数组中不存在目标元素,则返回 -1

let list = [1, 2, 3];let index1 = list.indexOf(1); // 结果为 0
let index2 = list.indexOf(4); // 结果为 -1

lastIndexOf() 功能类似,但是从后往前查找

let list = [1, 2, 3, 1];let index = list.lastIndexOf(1); // 结果为 3

判断数组是否包含目标元素

方式一:includes()【推荐】

目标数组.includes(目标元素)
[1, 2, 3].includes(2); // true// 第二个参数表示搜索的起始位置,默认为 0 。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为 -4 ,但数组长度为 3 ),则会重置为从 0 开始。
[1, 2, 3].includes(3, 3); // false

方式二:indexOf()

let list = [1, 2, 3];if (list.indexOf(4) === -1) {console.log("list 数组中没有元素 4");
}

查找第一个符合条件的元素 find()

目标数组.find(返回搜索条件的函数)
let list = [1, 2, 3, 3];// 搜索到符合条件的元素,返回该元素
let result1 = list.find((item) => item > 2); // 得到 3// 若无符合条件的元素,返回 undefined
let result2 = list.find((item) => item > 4); // 得到 undefined

查找第一个符合条件的元素的下标 findIndex()

目标数组.findIndex(返回搜索条件的函数)
let list = [1, 2, 3, 3];// 搜索到符合条件的元素,返回该元素的下标
let result1 = list.findIndex((item) => item > 2); // 得到 2// 若无符合条件的元素,返回 -1
let result2 = list.findIndex((item) => item > 4); // 得到 -1

修改元素

目标数组[目标位置的下标] = 新的值
let list = [1, 2, 3];list[1] = 4; // list 变为 [ 1, 4, 3 ]

添加元素

在目标位置添加元素

方式1:splice 【推荐】

目标数组.splice(目标位置的下标, 删除元素的数量, 新元素);
  • 返回值为被删除元素组成的数组
let list = [1, 2, 3];// 在下标为 1 的地方添加元素 4
let result = list.splice(1, 0, 4); // list 变为 [ 1, 4, 2, 3 ] , result 的值为 []

方式2:下标赋值

目标数组[目标位置的下标] = 新元素
  • 若目标位置的下标 < 数组长度,则是修改元素
  • 若目标位置的下标 = 数组长度,则是在数组尾部添加新元素
  • 若目标位置的下标 > 数组长度,则 arr.length -1至 index-1之间为空属性,用下标访问时,得到 undefined

在数组头部添加元素 unshift()

即左侧,添加一个或多个元素,返回数组的新长度

let list = [1, 2, 3];//  list 变为 [ 0, 0.1, 1, 2, 3 ], result 的值为 5
let result = list.unshift(0, 0.1);

在数组尾部添加元素 push()

即右侧,添加一个或多个元素,返回数组的新长度

let list = [1, 2, 3];//  list 变为 [ 1, 2, 3, 4, 5 ], result 的值为 5
let result = list.push(4, 5);

删除元素

删除指定下标的元素 splice

目标数组.splice(指定下标, 1);
let list = [1, 2, 3];//  list 变为 [ 1, 3 ], result 的值为 [ 2 ]
let result = list.splice(1, 1);

不推荐使用 delete

let list = [1, 2, 3];// list 变为 [ 1, undefined , 3 ]
delete list[1];
  • 目标下标的元素会变为 undefined
  • 数组的长度不会发生改变!

删除第一个元素 shift

返回被删除的元素

let list = [1, 2, 3];// list 变为  [ 2, 3 ] , result 的值为 1
let result = list.shift();

删除最后一个元素 pop

返回被删除的元素

let list = [1, 2, 3];// list 变为 [ 1, 2 ] , result 的值为 3
let result = list.pop();

删除指定元素

https://blog.csdn.net/weixin_41192489/article/details/126179580

删除所有元素——清空数组

let list = [1, 2, 3];//方式1
list = [];      //方式2
list.length = 0; //方式3
list.splice(0);

拼接元素

, 拼接 toString()

let list = [1, 2, 3];let result = list.toString(); // 结果为 1,2,3

效果与 join() join(',') 相同

用目标字符拼接 join()

目标数组.join(目标字符)

因默认的拼接符为 , , 所以 join() join(',') 和 toString() 的效果相同。

let list = [1, 2, 3];
// 用 - 进行拼接
let result = list.join("-"); // 结果为 1-2-3

数组排序 sort()

https://blog.csdn.net/weixin_41192489/article/details/116696303

  • 对象数组排序
    https://blog.csdn.net/weixin_41192489/article/details/111400551

数组过滤 filter()

let list1 = [1, 2, 3];
// 过滤掉数组中小于 1 的元素
let list2 = list1.filter((item) => item > 1); // list2 为 [ 2, 3 ],不会改变 list1 

数组反转 reverse()

let list1 = [1, 2, 3];let list2 = list1.reverse(); // list1 和 list2 都为 [ 3, 2, 1 ]
  • 手写数组反转
    https://blog.csdn.net/weixin_41192489/article/details/116695073

数组合并 concat()

let list1 = [1, 2];
let list2 = [3, 4];let list3 = list1.concat(list2); // list3 为 [ 1, 2, 3, 4 ],list1 和 list2 不变let list4 = [5, 6];// 可同时合并多个数组
let list5 = list1.concat(list2, list4); // list5 为 [ 1, 2, 3, 4, 5, 6 ]

用 push 也可实现数组合并

let list1 = [1, 2];
let list2 = [3, 4];
let list3 = []
list3.push(...list1,...list2); // list3 为 [ 1, 2, 3, 4 ]

数组覆写 fill()

  • 第一个参数为填充的内容
  • 第二个参数为填充的起始下标(含头)
  • 第三个参数为填充的终止下标(不含尾)
let arr = ['a', 'b', 'c'];
// 若只有第一个参数,则所有元素都覆写为第一个参数
arr.fill(7)
//[ 7, 7, 7 ]['a', 'b', 'c'].fill(7, 1, 2)
//[ 'a', 7, 'c' ]

会改变原数组

let list = [1, 2];let result = list.fill(9); // result 和 list 都为 [ 9, 9 ]

数组截取 slice()

不会改变原数组

新数组 = 原数组.slice(开始位置的索引, 结束位置的索引); //注意:包含开始索引,不包含结束索引
  • slice() 是浅拷贝,对于引用类型的元素,拷贝的是地址,原数组改变时,会改变新数组
let list = [1, 2, 3];// 从下标 2 开始截取,直到数组末尾
let result1 = list.slice(2); // 结果为 [ 3 ]// 截取最后两个元素
let result2 = list.slice(-2); // 结果为 [ 2, 3 ]// 从下标 1 开始截取(含头),在下标 2 处停止截取(去尾)
let result3 = list.slice(1, 2); // 结果为 [ 2 ]// 起始下标 > 终点下标 时,无法截取到元素
let result4 = list.slice(4, 2); // 结果为 [ ]

数组拼接 splice()

https://blog.csdn.net/weixin_41192489/article/details/116694667

数组缩减 reduce()

可用于数据累积计算(如求和),数据统计,数组降维,数组去重等,详见 https://blog.csdn.net/weixin_41192489/article/details/116661854

数组的遍历

https://blog.csdn.net/weixin_41192489/article/details/140170995

数组的复制

浅拷贝

let list1 = [1, 2, 3];// 浅拷贝 -- 将 list1 中的数组地址,复制到 list2 中
let list2 = list1;// list1 改变时 ,list2 也会同步改变
list1[0] = 4;console.log(list2); // 结果为  [ 4, 2, 3 ]

深拷贝

函数封装 extend

function getType(o) {var _t;return ((_t = typeof o) == "object"? (o == null && "null") || Object.prototype.toString.call(o).slice(8, -1): _t).toLowerCase();
}function extend(destination, source) {for (var p in source) {if (getType(source[p]) == "array" || getType(source[p]) == "object") {destination[p] = getType(source[p]) == "array" ? [] : {};arguments.callee(destination[p], source[p]);} else {destination[p] = source[p];}}
}

使用

let list1 = [1, 2, 3];let list2 = [];// 深拷贝 -- 将 list1 中的数组复制一份,将复制后的数组的地址,存入 list2 中
extend(list2, list1);// list1 改变时 ,list2 不会发生改变
list1[0] = 4;console.log(list2); // 结果为 [ 1, 2, 3 ]

lodash 中的 cloneDeep 可轻松完成深拷贝

let list2 = _.cloneDeep(list1);

以下方式,可对简易数组(无嵌套,元素无正则,undefined,函数等)实现深拷贝:

let arr1 = [1, 2, 3]
// 仅深拷贝第一层,若存在嵌套则不适用
let arr2 = [...arr1] 
let arr1 = [1, 2, 3];
let arr2 = [];
for (let i = 0; i < arr1.length; i++) {// 仅深拷贝第一层,若存在嵌套则不适用arr2.push(arr1[i]);
}
// 若元素存在正则,undefined,函数等则不适用
let arr2 = JSON.parse(JSON.stringify(arr1))

数组的去重

https://blog.csdn.net/weixin_41192489/article/details/125988156

数组的交集、差集、补集、并集

https://blog.csdn.net/weixin_41192489/article/details/139855697

伪数组/类数组

https://blog.csdn.net/weixin_41192489/article/details/116642962

【实战】对象数组的分类统计

let Data = [{"province": "四川","boy": 8,"girl": 10},{"province": "湖北","boy": 2,"girl": 8},{"province": "四川","boy": 9,"girl": 6},{"province": "湖北","boy": 4,"girl": 7}
]let dataObj = {}
//遍历数组,item为数组的每一个对象
Data.forEach((item, index) => {//第一次添加该省时,初始化boy和girl的值为0if (dataObj[item.province] == undefined) {dataObj[item.province] = {boy: 0,girl: 0}}// 倘若boy或girl的值为null或undefined,则初始化为0item.boy = item.boy ? item.boy : 0item.girl = item.girl ? item.girl : 0// 按省进行累加统计dataObj[item.province] = {boy: dataObj[item.province].boy + item.boy,girl: dataObj[item.province].girl + item.girl}}
)console.log(dataObj)

此时dataObj的值为

{'四川': {boy: 17,girl: 16},'湖北': {boy: 6,girl: 15}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/872237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java用JDBC链接mysql

一、什么是JDBC&#xff1a; 是Java平台上的标准数据库访问技术。它提供了一套API&#xff08;应用程序编程接口&#xff09;&#xff0c;允许Java应用程序与各种类型的数据库进行交互&#xff0c;包括关系型数据库&#xff08;如MySQL、Oracle、SQL Server等&#xff09;和非关…

【日记】艾尔登法环终于玩完了(348 字)

正文 昨天打了一天游戏。法环差不多通关了。最终 boss 艾尔登鼻涕虫实在打不过&#xff0c;两个人开挂打了。艾尔登之兽老是马拉松&#xff0c;这谁顶得住&#xff0c;追都追不上。据兄长说&#xff0c;这游戏大概还有 50%-60% 的内容没玩&#xff0c;不过就这样吧&#xff0c;…

解决VMware虚拟机在桥接模式下无法上网的问题

解决VMware虚拟机在桥接模式下无法上网的问题 windows11系统自动启动了热点功能&#xff0c;开启热点可能会干扰虚拟机的桥接设置。 方法一&#xff1a;windows11可以提供网络热点服务 方法二&#xff1a;手动指定桥接的物理网卡 方法一&#xff1a;关闭热点功能 优点&#xff…

MYSQL 四、mysql进阶 10(数据库其它调优策略)

一、数据库调优的措施 1.1 调优的目标 尽可能节省系统资源 &#xff0c;以便系统可以提供更大负荷的服务。&#xff08;吞吐量更大&#xff09;合理的结构设计和参数调整&#xff0c;以提高用户操作响应的速度 。&#xff08;响应速度更快&#xff09;减少系统的瓶颈&#xff…

13 循环神经网络—序列模型,语言模型

目录 1.序列模型序列数据统计工具自回归模型马尔可夫模型因果关系前向算法举例(根据过去的事件推测未来的事件)方案 A -马尔科夫假设方案 B -潜变量模型总结代码实现 使用马尔科夫假设 训练一个MLP2.文本预处理常见的文本预处理步骤代码实现3.语言模型**使用计数来建模**N 元…

VUE前端HTML静默打印(不弹出打印对话框)PDF简单方案

前言 在做打印功能的时候&#xff0c;以前大部分客户端都是用C#做的&#xff0c;静默打印&#xff08;也就是不弹出打印对话框&#xff09;比较简单。 但是使用浏览器作为客户端&#xff0c;静默打印&#xff08;也就是不弹出打印对话框&#xff09;做起来就比较困难。困难的…

getaddrinfo 获取地址信息(C语言函数库/CRT)

getaddrinfo 是POSIX定义的通用函数&#xff0c;该函数可以在 Windows、MacOS X、Linux、Android 等平台正确编译且工作。 getaddrinfo 函数的作用为&#xff1a;解释域/IP的地址信息&#xff0c;可简易理解为DNS解析函数。 static IPEndPoint Ipep_GetEndPointWithNative(cons…

python笔记(转存ipynb)------1

list1 ["tom","cat","Lili"] print(list1[0].title())Tom#append()列表方法在列表末尾添加新元素 list1.append(233) print(list1) #可以先创建空列表&#xff0c;再进行追加append(..)以添加[tom, cat, Lili, 233]#insert()列表方法插入元素 l…

29.【C语言】自定义函数

1、自定义详解 *提示&#xff1a;先看第12,19篇 例&#xff1a;写一个程序交换两个变量的值 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void swap(int x, int y) {int z 0;z x;x y;y z; } int main() {int a 10;int b 20;swap(a, b);printf("%d…

让AI语言模型自由飞翔:LangChain框架的奇妙世界

今天&#xff0c;我将为大家揭开一项令人激动的技术——LangChain。想象一下&#xff0c;如果能将人工智能的强大能力与我们日常使用的数据和工具无缝连接&#xff0c;那将开启怎样崭新且无限的可能&#xff01; LangChain&#xff0c;一个专为大型语言模型设计的框架&#xf…

TG创建小程序交互APP登录以及机器人信息

1、搜索 BotFather &#xff0c;输入命令 /newbot 创建机器人。 2、修改机器人信息 /mybots 编辑名称 : 修改机器人名称 编辑关于: 修改关于 hayden yyds&#xff0c;修改以后打开机器人会出现在下图 编辑描述 : 机器人的描述 编辑描述图片 : 机器人的图片 编辑 Botpic…

瑞幸私域运营案例拆解

1. 私域运营概述 私域运营是一种以用户为中心的运营模式&#xff0c;通过建立和维护与用户之间的直接联系&#xff0c;实现品牌与用户之间的深度互动和长期价值挖掘。 1.1 私域流量定义 私域流量指的是企业通过自有渠道&#xff0c;如微信公众号、小程序、社群等&#xff0c…

SQL进阶技巧:如何按照固定尺寸(固定区间)对数据进行打分类标签?

目录 0 问题引入 应用案例1 应用案例2 小结 0 问题引入 在日常数据分析中,经常会遇到数据产品经理或数据分析师提出这样的需求,比如按照某一给定的区间或数据范围对数据进行分类标签,而遇到这样的问题,好多同学感觉SQL做起来有点困难或无从下手,其实面对这样的问题笔者…

[C++] 匿名命名空间

匿名命名空间是C中的一种特性&#xff0c;它允许你在不指定名称的情况下声明一个命名空间。这种命名空间主要用于局部作用域&#xff0c;例如在一个源文件的顶层&#xff0c;来限制符号的作用范围&#xff0c;从而避免全局命名空间中的命名冲突。 匿名命名空间中的所有声明都自…

.gitignore配置文件不生效的问题

一、问题描述&#xff1a; 在已经提交过的git管理的项目中&#xff0c;新增加一个.gitignore文件&#xff0c;或者修改.gitignore文件之后&#xff0c;新增的忽略内容不生效 二、问题原因&#xff1a; gitignore文件只能作用于Untracked Files的文件&#xff0c;也就是那些从…

【通信协议-RTCM】MSM语句(1) - 多信号GNSS观测数据消息格式

注释&#xff1a; RTCM响应消息1020为GLONASS星历信息&#xff0c;暂不介绍&#xff0c;前公司暂未研发RTCM消息类型版本的DR/RTK模块&#xff0c;DR/RTK模块仅NMEA消息类型使用 注释&#xff1a; 公司使用的多信号语句类型为MSM4&MSM7&#xff0c;也应该是运用最广泛的语句…

暑期备考2024上海初中生古诗文大会:单选题真题和独家解析

现在距离2024年初中生古诗文大会初选还有不到4个月&#xff08;11月3日正式开赛&#xff09;&#xff0c;我们继续来看10道选择题真题和详细解析。为帮助孩子自测和练习&#xff0c;题目的答案和解析统一附后。 本专题持续分享。 一、上海初中古诗文大会历年真题精选(参考答案…

探索IP形象设计:快速掌握设计要点

随着市场竞争的加剧&#xff0c;越来越多的企业开始关注品牌形象的塑造和推广。在品牌形象中&#xff0c;知识产权形象设计是非常重要的方面。在智能和互联网的趋势下&#xff0c;未来的知识产权形象设计可能会更加关注数字和社交网络。通过数字技术和社交媒体平台&#xff0c;…

等保测评是什么 怎么做

在信息安全日益受到重视的今天&#xff0c;等保测评已成为企事业单位不可或缺的安全合规活动。然而&#xff0c;对于等保测评的理解和实施&#xff0c;仍存在诸多误区。本文将对等保测评的周期、法律责任、网络环境、测评对象、费用及常见误区进行深入解析&#xff0c;以期帮助…

源码安装zabbix5.0.36完整版

源码安装zabbix5.0.36完整版 环境&#xff1a;CentOS Linux release 7.9&#xff0c;cpu:16&#xff0c;mem:32G软件包如下&#xff1a; zabbix-5.0.36.tar.gz mysql-8.0.28-linux-glibc2.17-x86_64-minimal.tar.xz nginx-1.6.2.tar.gz 1. 配置前准备 systemctl stop firewa…