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] = item
    arr.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] = item
    arr.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.size

    return 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)); // true
    console.log(arr.length); // 5
    arr.forEach(function (item) {
      console.log(item);
    });

    // 读取/查找
    console.log(arr[2]); // 3
    console.log(arr.indexOf(4)); // 3
    console.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()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt QLabel标签控件

文章目录 1 属性和方法1.1 文本1.2 对齐方式1.3 换行1.4 图像 2. 实例2.1 布局2.2 为标签添加背景色2.3 为标签添加图片2.4 代码实现 QLabeI是Qt中的标签类&#xff0c;通常用于显示提示性的文本&#xff0c;也可以显示图像 1 属性和方法 QLabel有很多属性&#xff0c;完整的可…

鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业电子招采平台

随着企业的快速发展&#xff0c;招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求&#xff0c;建立一个公平、公开、公正的采购环境至关重要。在这个背景下&#xff0c;我们开发了一款电子招标采购软件&#xff0c;以最大限度地控制采购成本&#…

Spring MVC学习之——入门

Spring MVC 介绍 Spring MVC 是Spring框架的一个模块&#xff0c;是一个基于 MVC 设计模式的轻量级 Web 开发框架&#xff0c;本质上相当于 Servlet。 SpringMVC 是 Spring 为表示层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的…

作业--day43

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数&#xff0c;将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c…

图像分割实战-系列教程12:deeplab系列算法概述

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 1、空洞卷积 图像分割中的传统做法&#xff1a;为了增大感受野&#xff0c;通常都会选择pooling操…

centos7 yum添加源或换源

yum添加源或换源 一般来说yum源是我们需要下载的软件的远程仓库地址(当然也可以配置本地源)&#xff0c;centos系统带有几个官方源&#xff0c;默认启用的仅有base,updates和extras三个。有时我们需要的软件在官方源中没有&#xff0c;这时我们就需要添加第三方源或换默认源。…

Halcon根据灰度特征值选择区域select_gray

Halcon根据灰度特征值选择区域 与select_shape算子类似&#xff0c;灰度值图像也可以快捷地根据特征值选择符合设定条件的区域。select_gray算子用于实现这一功能&#xff0c;该算子能接受一组区域作为输入&#xff0c;然后根据选定的特征计算其是否满足特定的条件。当所有区域…

1.5号io网络

僵尸进程和孤儿进程 僵尸进程 孤儿进程 守护进程 1.守护进程相当于一个服务&#xff0c;不依赖于终端而存在 2.守护进程随着系统的启动而启动&#xff0c;关闭而关闭 3.守护进程创建流程 1、创建一个孤儿进程 2、重设守护进程的会话id和组id 3、修改守护进程的操作目录为…

指定linux文件夹下所有文件赋权命令“chmod -R 755”

仓库&#xff1a;Ai-trainee/GPT-Prompts-Hub 下面我们假设要为&#xff1a;/opt/robot/lib/robot_control/下所有子文件赋权 如果要为 robot_control 目录中的所有文件分配权限&#xff08;在 Linux 术语中也称为“更改文件权限”或“chmod”&#xff09;&#xff0c;则可以…

【从零开始学技术】Fiddler 抓取 https 请求大全

1.Fiddler代理浏览器设置 注意浏览器代理区别 Chrome/IE浏览器使用的都是系统代理设置 在chrome浏览器的设置中搜索代理&#xff0c;可以看到 打开IE浏览器&#xff0c;选择设置->Internet选项 Firefox浏览器使用的是单独的一套代理系统 在Firefox的代理设置中&#xff0c;我…

锂电池放电结束后电压回升,充电结束后电压下降

放电时&#xff0c;撤去负载&#xff0c;开路电压会上升&#xff1b;充电时&#xff0c;撤去电源&#xff0c;开路电压会下降。 一、极化 极化是指事物在一定条件下发生两极分化&#xff0c;使其性质相对于原来状态有所偏离的现象。 二、电化学极化 对于任何电化学体系中&am…

java注解学习

java注解 Annotation 为什么要学注解&#xff1f; 在日常开发中&#xff0c;基本都是在使用别人定义或是各种框架的注解&#xff0c;比如Spring框架中常用的一些注解&#xff1a;Controller、Service、RequestMapping&#xff0c;以此来实现某些功能&#xff0c;但是却不知道如…

玩转硬件之C51的玩法(二)——模拟按键模块

模拟按键模块是一种常见的电子元件&#xff0c;它具有简单、易用、可靠的特点&#xff0c;被广泛应用于各种电子设备中。它的工作原理是通过按下按钮&#xff0c;使开关接通或断开电路&#xff0c;从而实现控制电子设备的功能。 AD Keyboard模块可以适用Arduino和C51&#xff…

xss-labs(6-9)

level6:欢迎来到level6 老规矩还是先看看输入框的闭合情况 尝试事件函数绕过 test" onclick="alert(欢迎来钓鱼) 既然事件函数被转义了,那就使用我们第二关用过的绕过方法插入标签看看 test"><script>alert(欢迎来钓鱼)</script>// <

Excel:通过excel将表数据批量转换成SQL语句

这里有一张表《student》&#xff0c;里面有10条测试数据&#xff0c;现在将这10条测试数据自动生成 insert语句&#xff0c;去数据库 批量执行 P.S. 主要用到excel表格中的 CONCATENATE函数&#xff0c;将单元格里面的内容填入到sql里面对应的位置 1. 先写好一条insert语句&a…

定时器中断控制的独立式键盘扫描实验

#include<reg51.h> //包含51单片机寄存器定义的头文件 sbit S1P1^4; //将S1位定义为P1.4引脚 sbit S2P1^5; //将S2位定义为P1.5引脚 sbit S3P1^6; //将S3位定义为P1.6引脚 sbit S4P1^7; //将S4位定义为P1.7引脚 unsigned char keyval; /…

WPF 基础入门(资源字典)

资源字典 每个Resources属性存储着一个资源字典集合。如果希望在多个项目之间共享资源的话&#xff0c;就可以创建一个资源字典。资源字段是一个简单的XAML文档&#xff0c;该文档就是用于存储资源的&#xff0c;可以通过右键项目->添加资源字典的方式来添加一个资源字典文件…

如何实现在IDEA中远程访问家里或者公司的数据库远程协作开发

文章目录 1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql小结 5. 固定连接公网地址6. 固定地址连接测试 IDEA作为Java开发最主力的工具&#xff0c;在开发过程中需要经常用到数据库&#xff0c;如Mysql数据库&#xff0c;但是在IDEA中只能连接本…

批量剪辑方法:掌握视频剪辑技巧,按指定时长轻松分割视频

在视频制作和编辑过程中&#xff0c;经常要批量处理和剪辑大量的视频片段。学会批量剪辑方法可以提高工作效率&#xff0c;还可以使视频编辑更加准确和高效。下面来看下云炫AI智剪如何按指定时长轻松分割视频的批量剪辑方法。 分割后的视频文件效果&#xff0c;已分割分段的视…

B端企业画像的数据获取和构建

什么是企业画像&#xff1f; 不管是企业画像还是C端用户画像&#xff0c;都需要展示两类属性&#xff1a; 企业本身的属性&#xff1b;依赖于客户和企业关系的画像&#xff0c;这部分属性就是我们在企业画像中要做的重要内容。 举个例子&#xff1a;某餐厅是A产品进货的客户…