js(JavaScript)数据结构之数组(Array)

什么是数据结构?

下面是维基百科的解释:

数据结构是计算机存储、组织数据的方式。数据结构意味着接口或封装:一个数据结构可被视为两个函数之间的接口,或者是由数据类型联合组成的存储内容的访问方法封装。

我们每天的编码中都会用到数据结构,下面是常见的数据结构:

  • 数组(Array)
  • 栈(Stack)
  • 队列(Queue)
  • 链表(Linked List)
  • 散列表(Hash)
  • 字典
  • 树(Tree)
  • 图(Graph)
  • 堆(Heap)

数组(Array)

在计算机科学中,数组数据结构(英语:array data
structure),简称数组(英语:Array),是由相同类型的元素(element)的集合所组成的数据结构,分配一块连续的内存来存储。利用元素的索引(index)可以计算出该元素对应的存储地址。——维基百科

数组经常使用的场景:待办事项列表、购物清单、最佳十名榜单等等。

数组是计算机科学中的一种数据结构,用于存储一系列相同类型的元素,并将它们存在连续的内存中。通过索引可以找到存储地址。

适用场景

  • 适用:简单数据结构、不需要频繁查找或排序
  • 不适用:复杂数据结构、需要频繁操作和查找

创建数组

  • Array 构造函数:new Array()new Array(1, 2, 3),需要 new 关键字
  • 方括号 [][][1, 2, 3],更简洁

1、Array构造函数

var arr1 = new Array();  //创建空数组
var arr2 = new Array(1,2,3); //创建元素为1,2,3的数组
var arr3 = new Array(5);  //创建长度为5的数组

Array构造函数,需要使用new关键字。

2、使用方括号[]

var arr1 = [] ;  //创建一个空数组
var arr2 = [4,5,6];  //创建元素为4,5,6的数组

判断、长度和遍历数组

  • Array.isArray(arr):判断是否是数组
  • arr.length:获取数组长度
  • 遍历方式:forforEachmapfiltersomeeveryfind

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

Array.isArray(arr1);
结果输出为: true

判断数组的长度
数组有一个属性length,可以用来获取数组的长度。

var arr2 = [4,5,6,7];
var length = arr2.length;
结果输出为: 4

遍历数组
方式一:for循环遍历数组

for(var i = 0; i < arr.length; i++) {console.log(arr[i]);
}

方式二:forEach遍历数组
forEach()在原数组的基础上改变,没有返回值,在function内进行操作

arr.forEach( function (i) {console.log(i);
});

方式三:map遍历数组
map()会返回一个新数组,原数组不会改变。

var arr = [1,2,3];
var arr1 = arr.map(function (i) {return i * i;
});
结果:arr1 = [1,4,9]

方式四:filter遍历数组
过滤筛选,返回一个新数组,原数组不会改变。

var arr = [1,2,3,4,5,6,7,8,9];
var arr1 = arr.filter(function(i) {return i%2==0;
});
结果:arr1 = [2,4,6,8]

方式五:some遍历检测数组中是否有元素满足条件
如果有一个元素满足条件,则返回true,剩下的元素不会再进行检测
如果全部遍历结束,没有满足条件的元素,则返回false

var arr = [10,17,12,11];
arr.some(function(i){return i >15;
);
结果:true

方式六:every遍历检测数组是否所有元素都满足条件

var arr = [17,10,18,15];
arr.every(function(i){return i > 11;
});
结果:false

方法七:find遍历返回通过测试的数组的第一个元素的值
当数组中的元素满足条件时,find()返回符合条件的这个元素,剩下的元素不会再进行检测
如果没有符合条件的元素则返回undefined

var arr = [10,12,15,19,111];
arr.find(function(i){return i > 14;
});
结果:15

基本操作

  • 读取/查找arr[index]indexOflastIndexOf
  • 更新/替换:直接赋值或使用 splice()

插入和删除元素

  • 插入unshift()(首部)、push()(尾部)、splice()(中间)
  • 删除pop()(尾部)、shift()(首部)、splice()(中间)
读取元素/查找运算

JavaScript 中通过 数组[下标] 的方式来访问数组中指定下标的元素值,数组下标从0开始。

let arr = [1,5,2,4,4,3,2,14]
console.log(arr[5]) // 3

indexOf()
查找某个字符串在要查询的字符串中首次出现的位置的索引值

var arr = [1,2,3,4,3,2,1];
var n = arr.indexOf(3);
结果: n = 2;

lastIndexOf()
查找某个字符串在要查询的字符串中最后一个出现的索引值

var arr = [1,2,3,4,3,2,1];
var  n = arr.lastIndexOf(3);
结果:n = 4;

注意:如果某字符串中只有一个要查询的字符串,那么lastIndexOf和indexOf结果是一样的。

更新元素/替换元素

数组元素值的更新原理与访问原理一致,也是通过先计算出要更新的内存区域,然后再对其进行修改。

JavaScript 中通过 数组[下标] = 值 的方式对数组中指定位置的值进行修改。

let arr = [1,5,2,4,4,3,2,14]
arr[5] = 100
console.log(arr[5]) // 100

splice()方法
splice(index,length,new_arr)

  • index:从第几个元素开始替换
  • length:需要替换的元素的个数
  • new_arr:替换出来的元素存储在new_arr里

这个方法的返回结果是被截取的部分

使用splice()进行替换:var arr = [1,2,3,4,5,6];
var arr1 = arr.splice(0,2,9);
结果:arr = [9,3,4,5,6];  arr1 = [1,2];
使用splice()进行删除:var arr = [1,2,3,4,5,6];
arr.splice(2,3);
结果:arr = [1,2,6];   arr1 = [3,4,5];
使用splice()进行插入:var arr = [1,2,3,4,5,6];
arr.splice(2,0,10,11,12);
结果:arr = [1,2,10,11,12,3,,4,5,6];
插入元素/添加元素

数组的实际元素数量有可能小于数组的长度

let arr = new Array(8); //定义长度为8的数组,在内存中会为我们分配8个元素的空间// 初始化:对数组前6个元素赋值
arr[0] = 1;
arr[1] = 5;
arr[2] = 2;
arr[3] = 4;
arr[4] = 4;
arr[5] = 3;arr.size = 5 // 代表当前数组的实际使用长度

首位插入
unshift()
向数组首位插入元素,可插入多个

var arr = [1,2,3,4,5,6];
arr.unshift(0);
结果:arr = [0,1,2,3,4,5,6];

尾部插入
尾部插入,是最简单的情况,直接把插入的元素放在数组尾部的空闲位置即可,等同于更新元素的操作

如果需要在数组最后插入一个1,直接对当前数组最后一项赋值即可

arr[6] = 1 // 对第6个元素赋值console.log(arr) // [ 1, 5, 2, 4, 4, 3, 1, <1 empty item> ]

push()
向数组末位插入入元素,可插入多个

var arr = [1,2,3,4,5,6];
arr.push(7);
结果:arr = [1,2,3,4,5,6,7];

配合length使用
向数组末位插入一个元素

var arr = [1,2,3,4,5,6];
ar[arr.length] = 8;
结果:arr = [1,2,3,4,5,6,8];

中间插入
由于数组的每一个元素都有其固定下标,所以不得不首先把插入位置及后面的元素向后移动,腾出地方,再把要插入的元素放到对应的数组位置上;
如果需要在数组第三个位置后插入一个1,那么需要想将第三个位置以及后面的元素全部向后移动一位,留出空闲的位置后再对其进行修改操作。

// 向数组中下标为 index 的位置插入一个item值
function arrayAddItem(arr, index, item) {// 将第item后的元素全部向后移动一位for(let i = arr.size; i > index; i--){// 移动arr[i] = arr[i-1]}// 将要插入的值赋值到指定位置arr[index] = itemarr.size++return arr
}arr = arrayAddItem(arr, 3, 1)
console.log(arr); // [ 1, 5, 2, 1, 4, 4, 3, <1 empty item> ]

超范围插入

由于数组的长度是不可变的,所以一个数组分配到的内存空间也是固定的。前面都是在数组中元素数量小于数组长度的情况下插入元素的。

let arr = [1,2,3,4,5]
arr.size = 5 // 当前数组是使用长度// 向数组中下标为 index 的位置插入一个item值
function arrayAddItem(arr, index, item) {if(arr[arr.length-1]){// 数组中的元素数量已经满了,扩容数组arr = expandArray(arr)}// 将第item后的元素全部向后移动一位for(let i = arr.size; i > index; i--){// 移动arr[i] = arr[i-1]}// 将要插入的值赋值到指定位置arr[index] = itemarr.size++return arr
}// 扩容数组为原来长度的两倍
function expandArray(arr){// 创建一个长度为原来长度两倍的数组let newArray = new Array(arr.size * 2)// 将原来的数组复制到新的数组中for (let i = 0; i < arr.size; i++) {newArray[i] = arr[i]}newArray.size = arr.sizereturn newArray
}arr = arrayAddItem(arr, 3, 1)
console.log(arr); [ 1, 2, 3, 1, 4, 5, <4 empty items>]
删除元素

数组的删除操作和插入操作的过程相反,如果删除的元素位于数组中间,其后的元素都需要向前挪动1位

function arrayRemoveItem(arr, index){for (let i = index; i < arr.size-1; i++) {// 后面一项往前移动arr[i] = arr[i+1]}// 当前项算法为最后一项delete arr[arr.size-1]arr.size--return arr
}

如果对数组元素没有顺序要求,删除操作还存在一种取巧的方法:

function arrayRemoveItem(arr, index){// 最后一项移动到被删除的位置arr[index] = arr[size-1]// 移除最后一项delete arr[size-1]size--return arr
}

pop()
把数组末尾的元素去除,并返回这个元素

var arr = [1,2,3,4,5,6];
var number = arr.pop();
结果:arr = [1,2,3,4,5]; number = 6;

shift()
把数组开头的元素去除,并返回这个元素

var arr = [1,2,3,4,5,6];
var number = arr.shift();
结果:arr = [2,3,4,5,6]; number = 1;

其他操作

  • 排序和反序sort()reverse()
  • 连接concat()
  • 转换为字符串join()toString()
  • 填充fill()
反序reverse()

用来反转数组的

var arr = [1,2,3,4];
arr.reverse();
结果:arr = [4,3,2,1];
排序sort()

按照字典顺序对元素进行排序,用来排序数组的,并且你也可以自定义排序规则,只需要传入一个函数即可

var arr = [8,5,6,2,3,1];
arr.sort();
结果:arr = [1,2,3,5,6,8];
arr = ['sunshine_lin','sanxin_lin','digger_lin']
console.log(arr.sort())
//['digger_lin','sanxin_lin','sunshine_lin' ]
console.log(arr)
//['digger_lin','sanxin lin','sunshine lin'
console.log(arr.sort((a,b) => b,length - a.length)) // 根据字符串长度排序
//['sunshine_lin','digger_lin','sanxin_lin' ]console.log(arr)
// [ 'sunshine_lin','digger_lin','sanxin_lin']
连接concat()

连接两个或者多个数组,并且返回该数组。

var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1.concat(arr2);
结果:arr1 = [1,2,3,4,5,6];
数组转换为字符串

join()

var arr = [1,2,3,4,5];
arr.join();
结果为:"1,2,3,4,5"

toString()

var arr = ["a","b","c","d"];
arr.toString();
结果为:“a,b,c,d”
fill 填充

用来把数组填满成自己想要的元素

arr = ['sunshine_lin','sanxin_lin','digger_lin']
console.log(arr.fill(0))
// [0, 0, 0]
console.log(arr)
// [0, 0, 0]
console.log(new Array(5).fill('哈哈哈哈哈哈'))
//  ['哈哈哈哈哈哈', '哈哈哈哈哈哈', '哈哈哈哈哈哈', '哈哈哈哈哈哈', '哈哈哈哈哈哈']

参考效果

请添加图片描述
参考代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Array操作示例</title>
</head><body><script>var arr = [1, 2, 3, 4, 5]; // 创建数组// 判断、长度和遍历数组console.log(Array.isArray(arr)); // trueconsole.log(arr.length); // 5arr.forEach(function (item) {console.log(item);});// 读取/查找console.log(arr[2]); // 3console.log(arr.indexOf(4)); // 3console.log(arr.lastIndexOf(2)); // 1// 更新/替换arr[1] = 6;console.log(arr); // [1, 6, 3, 4, 5]arr.splice(2, 1, 7);console.log(arr); // [1, 6, 7, 4, 5]// 插入和删除元素arr.unshift(0);console.log(arr); // [0, 1, 6, 7, 4, 5]arr.push(8);console.log(arr); // [0, 1, 6, 7, 4, 5, 8]arr.splice(3, 0, 9);console.log(arr); // [0, 1, 6, 9, 7, 4, 5, 8]arr.pop();console.log(arr); // [0, 1, 6, 9, 7, 4, 5]arr.shift();console.log(arr); // [1, 6, 9, 7, 4, 5]arr.splice(2, 1);console.log(arr); // [1, 6, 7, 4, 5]// 其他操作arr.sort();console.log(arr); // [1, 4, 5, 6, 7]arr.reverse();console.log(arr); // [7, 6, 5, 4, 1]var newArr = arr.concat([2, 3]);console.log(newArr); // [7, 6, 5, 4, 1, 2, 3]var str = arr.join('-');console.log(str); // "7-6-5-4-1"arr.fill(0);console.log(arr); // [0, 0, 0, 0, 0]</script>
</body></html>

优势与劣势

  • 优势:快速随机访问、高效的查找(如二分查找)
  • 劣势:插入和删除操作影响性能,需要移动大量元素

适用场景

数组适用于读取操作多、写操作少的情况。

持续学习总结记录中,回顾一下上面的内容:
创建数组
Array 构造函数:new Array() 或 new Array(1, 2, 3),需要 new 关键字
方括号 []:[] 或 [1, 2, 3],更简洁
判断、长度和遍历数组
Array.isArray(arr):判断是否是数组
arr.length:获取数组长度
遍历方式:for、forEach、map、filter、some、every、find
基本操作
读取/查找:arr[index]、indexOf、lastIndexOf
更新/替换:直接赋值或使用 splice()
插入和删除元素
插入:unshift()(首部)、push()(尾部)、splice()(中间)
删除:pop()(尾部)、shift()(首部)、splice()(中间)
其他操作
排序和反序:sort()、reverse()
连接:concat()
转换为字符串:join()、toString()

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

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

相关文章

Vue3+TS+Vite 构建自动导入开发环境

关注⬆️⬆️⬆️⬆️ 专栏后期更新更多前端内容 在一个使用 Vue 3、Vite 和 TypeScript 的项目中,配置 unplugin-auto-import 和 unplugin-vue-components 插件可以极大地提高开发效率,因为它们可以自动导入 Vue 相关的 API 和 Vue 组件,从而减少了手动导入的需要。 文章目…

Python——数据类型转换

# 将数字类型转换成字符串 num_str str(111) print(type(num_str), num_str) \# 将浮点类型转换成字符串 float_str str(12.34) print(type(float_str), float_str) # 将字符串转变成数字 num int("234") print(type(num)) # 将字符串转变成浮点型 num2 float(&q…

[论文精读]Brain Network Transformer

论文网址&#xff1a;[2210.06681] Brain Network Transformer (arxiv.org) 论文代码&#xff1a;GitHub - Wayfear/BrainNetworkTransformer: The open-source implementation of the NeurIPS 2022 paper Brain Network Transformer. 英文是纯手打的&#xff01;论文原文的s…

web端播放rtsp视频流(摄像头监控视频)教程

文章目录 前言一、ffmpeg是什么&#xff1f;二、ffmpeg安装1.下载2.安装 三、node搭建websocket服务四、web客户端播放视频 前言 像海康大华一些摄像头或者直播源 为rtsp视频流&#xff0c;想在web上播放必须进行协议转换。已知一些方案例如rtsp转rtmp需要flash&#xff0c;现…

将dumpbin从Visual Studio中抠出来,并使用dumpbin查看exe和dll库的依赖关系

目录 1、初步说明 2、在开发的机器上使用dumpbin工具查看dll库的依赖关系 3、将dumpbin.exe从Visual Studio中抠出来 3.1、找到dumpbin.exe文件及其依赖的dll文件 3.2、在cmd中运行dumpbin&#xff0c;提示找不到link.exe文件 3.3、再次运行dumpbin.exe提示找不到mspdb10…

SpringBoot-开启Admin监控服务

SpringBoot-Admin是一个用于管理和监控SpringBoot应用程序的开源项目。它提供了一个易于使用的Web界面&#xff0c;可以实时监控应用程序的健康状况、性能指标、日志和环境配置等信息。通过Actuator模块来收集和暴露应用程序的监控信息&#xff0c;使用Web Socket或者Server-Se…

SpringSecurity完整认证流程(包含自定义页面和自定义登录逻辑)

认证基本流程图&#xff1a; 1. 用户发起表单登录请求后&#xff0c;首先进入UsernamePasswordAuthenticationFilter ​ 在 UsernamePasswordAuthenticationFilter 中根据用户输入的用户名、密码构建了 UsernamePasswordAuthenticationToken&#xff0c;并将其交给 Authentic…

智能分析网关V4太阳能风光互补远程视频智能监控方案

一、背景需求 在一些偏远地区&#xff0c;也具有视频监控的需求。但是这类场景中&#xff0c;一般无法就近获取市电&#xff0c;如果要长距离拉取市电&#xff0c;建设的成本非常高且长距离传输有安全隐患&#xff0c;因此风光互补远程视频监控方案的需求也较多。利用风光电转化…

React Native 桥接原生实现 JS 调用原生方法

一、为什么需要桥接原生 为了满足在React 层无法实现的需求 复杂高性能的组件&#xff1a;复杂表格、视频播放原生层开发能力&#xff1a;传感器编程、widget平台属性&#xff1a;系统信息、设备信息对接第三方应用&#xff1a;相机、相册、地图 真实的开发过程中是不可能完…

开放平台系统架构设计

一、概述 背景与目标 本开放平台旨在构建一个可扩展、高可用的生态体系&#xff0c;通过提供统一标准的API接口和SDK工具包&#xff0c;让第三方开发者能够安全、高效地接入我们的服务和资源&#xff0c;实现业务的互联互通。 定位与功能描述 系统主要包含用户认证授权、资…

ffmpeg.c(4.3.1)源码剖析

文章目录 前言一、FFmpeg 源码结构图二、ffmpeg.h 头文件详解三、main 函数主要流程分析四、ffmpeg_parse_options1、命令行例子①、解析命令行 split_commandline()②、parse_optgroup()③、MATCH_PER_XXX_OPT() 2、vf 选项解析①、filters②、vf 术语③、avfilter_graph_pars…

阿里云RDMA通信库XRDMA论文详解

RDMA(remote direct memory access)即远端直接内存访问&#xff0c;是一种高性能网络通信技术&#xff0c;具有高带宽、低延迟、无CPU消耗等优点。RDMA相比TCP在性能方面有明显的优势&#xff0c;但在编程复杂度上RDMA verbs却比TCP socket复杂一个数量级。 开源社区和各大云厂…

微信扫码进入小程序特定页面

小程序配置 开发 - 开发管理 - 开发设置-普通链接二维码打开小程序 配置好的截图 如下&#xff1a;二维码规则建议是自己的域名 /mini/ 功能页面 pages/index/index 是为了方便跳转其他页面 记得把校验文件发给后端 web 端处理 二维码格式为&#xff1a;二维码规则/功能页…

怎么一边讲PPT一边录视频 如何一边录制PPT一边录制人像 录屏软件免费录屏 PPT录制怎么录制

随着新媒体技术的发展&#xff0c;短视频和直播越来越火。越来越多的小伙伴加入了视频制作的大军&#xff0c;那么你想知道怎么一边讲PPT一边录视频&#xff0c;如何一边录制PPT一边录制人像吗&#xff1f; 一、怎么一边讲PPT一边录视频 我们可以借助PPT本身自带的屏幕录制功能…

如何绘制PAD图和N-S图(详细步骤)

在软件详细设计阶段有四个要点&#xff1a;N-S图&#xff0c;PAD图&#xff0c;程序流程图&#xff0c;PDL语言 对于程序流程图的绘制较简单&#xff0c;想详细了解可以看&#xff1a; 程序流程图详解&#xff08;六大部分&#xff09; (zhihu.com) 对于PDL语言这里也不是重点…

Apache Doris (六十一): Spark Doris Connector - (1)-源码编译

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. Spark Doris Connector

Lava多模态大模型调试(基于vscode框架)

文章目录 前言一、整体概括二、launch.json文件配置三、调试展示前言 之前博客这里介绍LLava1.5多模态大模型的安装、训练、预测等。但对于你想查看源码或多或少都有些麻烦,也不利于代码调试。基于此,本文是一篇基于vscode框架调试llava大模型的教程。 一、整体概括 我是在…

基于net6的asp.net core webapi项目打包为docker镜像,并推送至私有镜像仓库harbor中

基于net6的asp.net core webapi项目打包为docker镜像&#xff0c;并推送至私有镜像仓库harbor中 0、环境说明1、打包步骤1.1 创建Asp.net core WebApi项目1.2 在Asp.net core WebApi项目根目录下创建Dockerfile文件1.3 在子系统Ubuntu20.04.4中通过docker build生成docker镜像1…

处理机调度与死锁

目录 进程调度算法先来先服务调度算法FCFS最短作业优先调度算法SJF最高优先级调度算法***HPF***高响应比优先调度算法 ***HRRN***时间片轮转调度算法***RR***多级队列调度算法MFQ 进程调度算法 进程调度算法也称为CPU调度算法 当 CPU 空闲时&#xff0c;操作系统就选择内存中…

Cacti 监控工具 | 因严重 SQL 注入漏洞而受到攻击

攻击者可以利用该问题访问Cacti数据库中的所有数据&#xff1b;并且&#xff0c;当与先前的漏洞链接时&#xff0c;它会启用 RCE。 用于监控网络性能的基于 Web 的 Cacti 开源框架中存在一个严重漏洞&#xff0c;该漏洞为攻击者提供了泄露 Cacti 整个数据库内容的方法&#xf…