网站首页 > 教程分享 正文
本章目标
- 掌握数组的定义和使用
- 掌握循环数组的方式
- 掌握获取数组中元素个数的方法
本章任务
- 能够计算班级所有学生的总成绩和平均成绩
- 能够求数组中的最大值
- 能够对数组排序
数组
为什么要学习数组
之前学习的数据类型,只能存储一个值(比如:Number/String。我们想存储班级中所有学生的考试成绩,此时该如何存储?
数组的概念
所谓数组,就是将多个元素(通常是同一类型)按一定顺序排列放到一个集合中,那么这个集合我们就称之为数组。
数组的定义
数组是一个有序的列表,可以在数组中存放任意的数据,并且数组的长度可以动态地调整。
// 定义一个空的数组,数组的字面量
let arr = [];
// 定义一个数组,存储5个学生的姓名
let names = ['刘备', '关羽', '赵云', '诸葛亮', '曹操'];
// 定义了一个数组,存储5个学生的成绩
let scores = [60, 89, 100, 55, 70];
数组存值
如果在给学生录入成绩的时候,输入错误,我们还可以更改学生的成绩。
数组中的数据使用索引(下标)管理,数组中的每一个数据都有一个序号(索引),但是要记住数组中的序号(索引)是从0开始的。
- 语法
// 索引从0开始
数组名称[索引] = 新值;
- 示例
let scores = [59, 70, 10];
// 修改第一个数据
scores[0] = 65;
// 修改最后一个数据
scores[2] = 60;
console.log(scores);
上面代码中,数组只有3个元素,最大的索引值为2。
如果班级里有5个学生的话,后两个学生的成绩该如何录入呢?
let scores = [59, 70, 10];
// 录入第4个和第5个学生的成绩
scores[3] = 99;
scores[4] = 100;
console.log(scores);
获取数组元素
学生的成绩我们已经可以存储到数组中了,那如何把存储到数据中的成绩获取出来计算总成绩呢?
把数据存储在数组里面,是为了将来能使用的,所以要从里面把数据取出来。数据取值同样使用索引取值
- 语法
数组名称[下标]
// 下标又称为索引,数组的下标是从0开始的
- 示例
let scores = [59, 70, 10];
// 获取第一个学生
console.log(scores[0]);
// 计算总成绩
let sum = socres[0] + scores[1] + scores[2];
把 数组名称[索引]格式当成一个变量使用
在上面代码的基础上,如果打印索引是3的元素,结果会是什么呢?
let scores = [59, 70, 10];
console.log(scores[3]); // undefined
可以发现,打印数组中不存在的元素,和使用定义未赋值的变量效果是一样的,输出的结果都是 undefined。
遍历数组
在获取数组元素中求总成绩的时候,我们把数组中的元素一个一个取出来累加求和,之前的数组中只有3个人的成绩,如果数组中存储的是30个人或者300个人的成绩,这个时候该如何求总成绩呢?
这个时候可以使用循环的方式来解决。
let scores = [60, 59, 80, 100];
let sum = 0;
// 在遍历数组的时候经常使用 for 循环
for (let i = 0; i <= 3; i++) {
sum += scores[i];
}
console.log(sum);
注意:数组中总共有4个元素,在遍历数组的时候索引从0开始,循环到数组的最大索引。此时的最大索引值是3。
我们求一个班的成绩可以这样实现,只要找到数组的最大索引就可以遍历数组。如果要求每一个班级的学生总成绩该如何做呢?不同班级的人数是不同的。
我们只需要知道数组的长度(数组中的元素个数)就可以计算数组中的最大索引
- 获取数组的元素个数
- 数组名称.length
let scores = [60, 59, 80, 100];
console.log(arr.length); // 4
获取到数组长度 数组.length,数组中的大索引值(最后一个索引值),只需要使用 数组.length - 1就可以获得,因为数组的索引是从0开始的。
let scores = [60, 59, 80, 100];
let sum = 0;
// 在遍历数组的时候经常使用 for 循环
for (let i = 0; i <= scores.length - 1; i++) {
sum += scores[i];
}
console.log(sum);
这里的条件还可以改成 i < scores.length
let scores = [60, 59, 80, 100];
let sum = 0;
// 在遍历数组的时候经常使用 for 循环
for (let i = 0; i < scores.length; i++) {
sum += scores[i];
}
console.log(sum);
清空数组
let arr = ['red', 'green', 'blue'];
arr = [];
// or
arr.length = 0;
案例
- 求一个数组中所有数字的总和和平均值
- 求数组中所有数字的最大值
- 求数组中最大值的索引
- 通过 prompt 让用户输出5个学生的成绩,存储到数组中,并求总成绩和平均成绩
冒泡排序
根据如图所示,我们要排序一组数,首先可以比较相邻的两个数,如果第一个数大于第二个数则交换位置,这样两两比较的之后,经过第一轮(这组数中两两比较结束)就可以获得这组数中的最大的那一个。而两两比较的次数总共需要 length - 1次。
假设数组为 [4, 3, 2, 1],第一轮比较过程如下:
- 4 3 2 1 > 3 4 2 1
- 3 4 2 1 > 3 2 4 1
- 3 2 4 1 > 3 2 1 4
我们把上面的这段话翻译成代码的形式,如下:
let arr = [10, 20, 30, 50];
// 循环数组,进行两两比较
for (let j = 0; j < arr.length - 1; j++) {
// 两两比较,把大的数往后移动
if (arr[j] > arr[j + 1]) {
// 交换两个数的位置
let tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
console.log(arr);
刚刚比较结束之后只找到到最大的数,排序并没有结束,还需要重复执行上面的代码,再找到倒数第二大的值、倒数第三大的值。如果数组中有 n 数,这个过程需要重复 n - 1 次。
假设数组为 [4, 3, 2, 1],第一轮比较过程如下:
- 4 3 2 1 > 3 4 2 1
- 3 4 2 1 > 3 2 4 1
- 3 2 4 1 > 3 2 1 4
上述是第一轮的过程,第二轮
- 3 2 1 4 > 2 3 1 4
- 2 3 1 4 > 2 1 3 4
第三轮
- 2 1 3 4 > 1 2 3 4
如果数组中有4个数字,总共需要三轮循环。
代码实现如下:
let arr = [10, 20, 30, 50];
// 控制比较的轮数
for (let i = 0; i < arr.length - 1; i++) {
// 进行两两比较的循环
for (let j = 0; j < arr.length - 1; j++) {
// 两两比较,把大的数往后移动
if (arr[j] > arr[j + 1]) {
// 交换两个数的位置
let tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
console.log(arr);
到此数组排序结束,但是这个内层循环,每轮比较的过程中都会循环 length - 1次,刚进过刚刚的拆解分析,我们可以得到如下结论:
- 第一轮,找最大值,两两比较次数 length - 1
- 第二乱,找倒数第二大的数(最大值已经确认),两两比较次数 length - 2
- 第三轮,找倒数第三大的数(倒数第一、二大的数已经确认),两两比较次数 length - 3
对内层循环进行优化,arr.length - i - 1
let arr = [10, 20, 30, 50];
// 控制比较的轮数
for (let i = 0; i < arr.length - 1; i++) {
// 进行两两比较的循环
for (let j = 0; j < arr.length i - 1; j++) {
// 两两比较,把大的数往后移动
if (arr[j] > arr[j + 1]) {
// 交换两个数的位置
let tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
对外层循环进行优化,我们之前使用的是一组特殊的数字 [4, 3, 2, 1],这组数就需要把每一轮的循环执行完,才能排序结束。
如果待排序的一组数是 [ 4, 1, 2, 3 ],这组数只需要一轮循环即可排序完成,还有可能是 [ 4, 3, 1, 2]。总之根据带排序的数组,外层循环有可能不需要完全循环完毕。
那外层循环多少次呢?这个不好确定。这里我们使用一个小技巧来优化外层循环。
如果内层循环中发生了交换,也就是排序还没有结束,这个时候外层循环要继续,如果某一轮循环中内层循环中不再交换两两元素的位置,我们就可以确认此时排序已经结束,跟着这个特点,我们来对代码进行优化。
let arr = [10, 20, 30, 50];
// 控制比较的轮数
for (let i = 0; i < arr.length - 1; i++) {
// 每一轮开始之前,假设排序结束
let flag = true;
// 进行两两比较的循环
for (let j = 0; j < arr.length - 1 - i; j++) {
// 两两比较,把大的数往后移动
if (arr[j] > arr[j + 1]) {
// 交换两个数的位置
let tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
// 如果发生两两交换,则排序没有结束
flag = false;
}
}
// 如果排序结束,跳出外层循环
if (flag) {
break;
}
}
console.log(arr);
参考:
- https://github.com/TonyLuo/Article
- https://algorithm-visualizer.org/brute-force/bubble-sort
补充:数组的构造函数
数组在 JavaScript 中还可以使用另一种方式创建,这个方式我们称为 : 构造函数
// 使用 构造函数 创建数组
let arr = new Array();
// 存储数据
arr[0] = 10;
arr[1] = 20;
console.log(arr);
也可以在创建的同时存储数据
let arr = new Array(10,20);
console.log(arr);
但是要注意,如果只有一个数据,不要使用这个方式存储数据
let arr = new Array(10);
console.log(arr); // 输出 [empty × 10]
这是因为,如果只给一个数字构造函数,它会认为你想要设置数组的长度,而不是要把数据存储在数组中。所以不能使用这个方式存储一个数字数据。如果非要存一个数据,使用别的方式存储。
作业
- 求数组中元素最小值
- 假设数组中的第一个元素是最小值
- 翻转数组
- 实现效果
- 假设数组为 ['a', 'b', 'c', 'd']
- 输出结果 ['d', 'c', 'b', 'a']
- 实现思路
- 倒序遍历原数组,初始值i = arr.length - 1,条件 i >= 0,i--
- 给新数组中的每一个元素赋值,可以通过 length 属性作为索引
- 将字符串数组用 | 或其他符号分割成字符串
- 实现效果
- 假设数组为 ['a', 'b', 'c', 'd']
- 输出结果 a|b|c|d
- 实现思路
- 先取出数组中的第一个元素存储到变量 s 中
- 从数组中的第二个元素开始遍历,在遍历到的元素前拼接分隔符,追加到变量s中
- s += '|' + arr[i]
- 将1-100中3的倍数放入到一个数组中
- 仿 siri 项目中实现求和的功能
- 当输入1进行求和的时候,首先让用户输入,他要计算多少个数字的和
- 再依次输入每个数字
- 最后打印求和的结果
猜你喜欢
- 2024-10-01 JavaScript 数组的常用方法(javascript数组有哪些方法)
- 2024-10-01 JavaScript中数组的方法(javascript数组有哪些方法)
- 2024-10-01 判断是否为数组的 JavaScript 方法总结
- 2024-10-01 JavaScript 中常用的数组操作方法
- 2024-10-01 JavaScript 数组常见操作(一)(javascript数组的方法)
- 2024-10-01 JavaScript之关联数组(关联数组和索引数组)
- 2024-10-01 程序员须知:高效的JavaScript数组方法
- 2024-10-01 JavaScript 数组方法的介绍(javascript中数组)
- 2024-10-01 JavaScript中5个值得被广泛使用的数组方法
- 2024-10-01 JavaScript 判断数组的方法总结,哪种最靠谱?
你 发表评论:
欢迎- 最近发表
-
- 有了这份900多页的Android面试指南,你离大厂Offer还远吗?
- K2 Blackpearl 流程平台总体功能介绍:常规流程功能
- 零基础安卓开发起步(一)(安卓开发入门视频)
- 教程:让你的安卓像Windows一样实现程序窗口化运行
- Android事件总线还能怎么玩?(事件总线有什么好处)
- Android 面试被问“谈谈架构”,到底要怎样回答才好?
- Android开发工具Parcel和Serialize
- Android 中Notification的运用(notification widget安卓)
- Android退出所有Activity最优雅的方式
- MT管理器-简单实战-去除启动页(mt管理器怎么去除软件弹窗)
- 标签列表
-
- css导航条 (66)
- sqlinsert (63)
- js提交表单 (60)
- param (62)
- parentelement (65)
- jquery分享 (62)
- check约束 (64)
- curl_init (68)
- sql if语句 (69)
- import (66)
- chmod文件夹 (71)
- clearinterval (71)
- pythonrange (62)
- 数组长度 (61)
- javafx (59)
- 全局消息钩子 (64)
- sort排序 (62)
- jdbc (69)
- php网页源码 (59)
- assert h (69)
- httpclientjar (60)
- postgresql conf (59)
- winform开发 (59)
- mysql数字类型 (71)
- drawimage (61)
本文暂时没有评论,来添加一个吧(●'◡'●)