JS 入门章节目录
第五章:数组
文章の目录
正文
JavaScript 数组用于在单一变量中存储多个值。
数组
什么是数组?
数组是一种特殊的变量,它能够一次存放一个以上的值。
数组可以用一个单一名称存放很多值,并且还可以通过引用索引号来访问这些值。
注:
- 索引,也叫下标,指元素在数组中存放的位置。
创建数组
使用数组文本
使用数组文本是创建 JavaScript 数组最简单的方法。
语法:
var array-name = [item1, item2, ...];
// 创建数组同时初始化
var cars = ["Saab", "Volvo", "BMW"];
// 创建空数组,然后向空数组中添加元素
var cars = [];
cars[0] = "Saab";
cars[1] = "Volvo";
cars[2] = "BMW";
注:
- 空格和折行并不重要。声明可横跨多行。
- 请不要在最后一个元素之后写逗号。
使用 JavaScript 关键词 new
语法:
var array-name = new Array(item1, item2, ...);
// 创建数组同时初始化
var cars = new Array("Saab", "Volvo", "BMW");
// 创建空数组,然后向空数组中添加元素
var cars = new Array();
cars[0] = "Saab";
cars[1] = "Volvo";
cars[2] = "BMW";
避免 new Array(),请使用 [ ] 取而代之
以上两种方法效果完全一样。没有必要使用 JavaScript 的内建数组构造器 new Array()。
new 关键词只会使代码复杂化,它还会产生某些不可预期的结果。所以出于简洁、可读性和执行速度的考虑,请使用第一种方法(数组文本方法)
访问和修改数组元素
访问数组元素
通过引用索引号(下标号)来引用某个数组元素。
语法:
array-name[i]
注:
- 数组索引从 0 开始,连续不重复,最大到 length - 1。
- array-name[i] 用法和单个变量完全一样。
改变数组元素
语法:
array-name[i] = value;
访问完整数组
通过 JavaScript,可以通过引用数组名来访问完整数组。
length 属性
length 属性返回数组的长度(数组中元素的个数)。
length 属性的值永远是最大下标 + 1。
注:
- 获取最后一个数组元素 —— arr[arr.length-1]
数组的遍历
for 循环
for(var i=0;i<arr.length;i++){
arr[i] // 即为数组的每一项
}
for in 循环
for(var key in arr){
key // 只是元素的下标
arr[key] // 当前元素值
}
三个不限制
1、不限制数组元素的个数:长度可变
2、不限制下标越界:
- 获取元素值:不报错。返回 undefined。
- 修改元素值:不报错。自动在指定位置创建新元素,并且自动修改 length 属性为最大下标 + 1。
3、不限制元素的数据类型
数组是对象
数组是一种特殊类型的对象。在 JavaScript 中对数组使用 typeof 运算符会返回 'object'。
但是,JavaScript 数组最好以数组来描述。
数组和对象的区别
在 JavaScript 中,数组使用数字索引。
在 JavaScript 中,对象使用命名索引。
数组是特殊类型的对象,具有数字索引。
何时使用数组,何时使用对象?
JavaScript 不支持关联数组。
如果希望元素名为字符串(文本)则应该使用对象。
如果希望元素名为数字则应该使用数组。
注:
关联数组:
- 很多编程元素支持命名索引的数组,具有命名索引的数组被称为关联数组(或散列)。
- JS 不支持命名索引的数组,在 JS 中,数组只能使用数字索引。
- 如果使用命名索引,JS 会把数组重定义为标准对象。之后,所有数组的方法和属性将产生非正确结果。
数组算法(操作)
数组求和,平均值,最值(最大值和最小值)
数组求和,平均值
// 随机生成十个学生的成绩([0,100]),并求其总分和平均分:
var score = [];
var sum = 0;
var avg;
// 循环生成学生成绩数组
for(var i = 0;i < 10;i++){
var num = Math.floor(Math.random() * 101);
score[i] = num;
}
// 遍历数组求和
for(var i in score){
sum += score[i];
}
// 求平均分
avg = sum / score.length;
console.log("学生成绩总分为:" + sum + ";平均分为:" + avg);
数组求最值
// 求十个学生成绩中的最值:
var score = [79, 98, 99, 85, 57, 39, 9, 75, 61, 78];
// 方法一:声明变量 maxIndex 存放最大值的索引。假设第一个元素(即索引为 0 的元素)为最大值,循环遍历数组,如数组元素比 maxIndex 标记的元素大,则更新 maxIndex 的值为当前元素的索引(即 i)。
// 最大值:
var maxIndex = 0;
for(var i = 0;i < score.length;i++){
if(score[i] > score[maxIndex]){
maxIndex = i;
}
}
console.log("学生成绩最大值为:" + score[maxIndex]);
// 我们没有必要将 maxIndex 和数组的第一个元素作比较(因为假设数组第一个元素为最大值)
var maxIndex = 0;
for(var i = 1;i < score.length;i++){
if(score[i] > score[maxIndex]){
maxIndex = i;
}
}
console.log("学生成绩最大值为:" + score[maxIndex]);
方法二:方法二和方法一很类似,只不过声明的 min 存放的是数组的最小值,而不是最小值的索引。
// 最小值:
var min = score[0];
for(var i in score){
if(score[i] < min){
min = score[i];
}
}
console.log("学生成绩最小值为:" + min);
查询(查找、验证)数组中是否存在某个值
循环遍历数组,若数组中存在该值,则打印输出,若不存在则返回提示信息。
注意要声明一个标记变量,该标记变量的作用是记录该值是否存在。
var nameArr = ["zhangsan","lisi","wangwu","zhaoliu","zhangsanfeng"];
var name = "";
var flag = 0; // 假设数组中不存在该元素,flag 也可以取值为 true。
for(var i = 0;i < nameArr.length;i++){
if(nameArr[i] == name){
console.log(name + " 存在于数组中,并且索引为:" + i);
flag = 1;
break;
}
}
if(flag == 0){
console.log("数组中不存在该元素。");
}
数组逆序
// 数组逆序
// 将第一个元素 arr[0] 和 最后一个元素 arr[arr.length-1-0] 交换位置
// 将第二个元素 arr[1] 和 倒数第二个元素 arr[arr.length-1-1] 交换位置
// 将第三个元素 arr[2] 和 倒数第三个元素 arr[arr.length-1-2] 交换位置
// ... ...
// 即将 arr[i] 处的元素 和 arr[arr.length-1-i] 处的元素交换位置
var arr = [1,2,3,4,5,6,7,8,9];
var temp; // 用于交换 arr[i] 和 arr[arr.length-1-i] 的位置
for(var i = 0;i <= arr.length/2-1;i++){ // 只需遍历数组的前一半元素(若遍历所有数组元素则不会倒置数组)
temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
console.log(arr);
数组排序
对数组中的元素按照从小到大(升序)或从大到小(降序)的顺序排序。
冒泡排序
// 嵌套 for 循环
// 外层循环 i 控制循环的次数(需要循环 arr.length-1 次)
// 内层循环 j 控制相邻元素之间的比较(需要比较 arr.length-i 次)
var arr = [2,6,4,8,1,9,5,3,7];
for(var i = 0;i < arr.length-1;i++){
for(var j = 0;j < arr.length-1-i;j++){
if(arr[j] > arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr);
数组方法
JavaScript 数组的力量隐藏在数组方法中。
数组转字符串
toString()
把数组转换为数组值(逗号分隔)的字符串。
toString() 方法不会修改原数组,而会返回新数组。
join()
将所有数组元素结合为一个字符串。类似于toString(),但是可以规定分隔符。
join() 方法不会修改原数组,而会返回新数组。
固定套路:
- 判断数组是否为空数组:arr.join("") == ""
- 将字符组成单词:chars.join("") -> 无缝拼接
- 将单词组成句子:words.join(" ")
- 将数组转化为页面元素的内容:"<开始标签>" + arr.join("</结束标签></开始标签>") + "</结束标签>"
toString() 和 join() 都不会直接修改原数组,而会返回新数组。
拼接和选取
拼接:concat()
concat() 方法通过合并(连接)现有数组来创建一个新数组。
concat() 方法不会修改原数组,而会返回新数组。
注:
- concat() 方法可以使用任意数量的数组参数。
- concat() 方法也可以将值作为参数。
语法:
var newArr = arr1.concat(值1,值2,arr2,arr3);
// 将值1,值2,arr2 中的每个元素,arr3 中的每个元素都拼接到 arr1 的元素之后,并且返回新数组
// arr2,arr3 的元素会被先打散,再拼接
选取:slice()
slice() 返回现有数组的一个子数组。
slice() 方法不会修改原数组,而会返回新数组。
语法:
var subArr = arr.slice(starti,endi+1)
// starti,endi+1 都为数组下标
// 选取 arr 中 starti 位置开始,到 endi 位置结束的所有元素组成新数组并返回,原数组保持不变
// 即 slice() 方法会从开始参数选取元素,直到结束参数(不包括)为止
强调:
凡是两个参数都是下标的方法,都有一个特性:含头不含尾。
选取简写:
- 一直选取到结尾:可省略第二个参数
- 如果选取的元素离结尾近:可用倒数下标
复制数组:
- arr.slice(0,arr.length); —— 可简写为:arr.slice();
concat() 和 slice() 都不会直接修改原数组,而会返回新数组。
修改数组
pop()
pop() 方法从数组中删除最后一个元素。
pop() 方法会修改原数组,并且返回“被弹出”的值。
push()
push() 方法在数组结尾处向数组添加一个或多个新的元素。
push() 方法会修改原数组,并且返回新数组的长度。
注:
- arr.push(value); 和 arr[arr.length] = value; 效果一样。
shift()
shift() 方法会删除首个数组元素,并把所有其他元素“位移”到更低的索引。
shift() 方法会修改原数组,并返回被“位移出”的元素。
unshift()
unshift() 方法在开头向数组添加新元素(一个或多个),并把所有其他元素“位移”到更高的索引。
unshift() 方法会修改原数组,并返回新数组的长度。
splice()
splice() 方法会直接修改原数组。
1、删除:
语法:
var deletes = arr.splice(starti,n);
删除 arr 中 starti 位置开始的 n 个元素。
返回值 deletes 保存了被删除的元素组成的临时数组。
注:
- 可以省略第二个参数 n,即为删除 arr 中 starti 位置开始到结尾的所有元素。
2、插入:
语法:
arr.splice(starti,0,值1,值2,...);
在 arr 中 starti 位置,插入值1,值2,...,原 starti 位置的值及其之后的值向后顺移。
3、替换:
其实就是删除旧的,插入新的。
语法:
arr.splice(starti,n,值1,值2,...);
先删除 arr 中 starti 位置的 n 个值,再在 starti 位置插入新值
返回值保存了被删除(被替换)的元素组成的临时数组
注:
- 删除的元素个数和插入的新元素个数不必一致
数组排序
reverse()
reverse() 方法反转数组中的元素(颠倒数组中元素的顺序)。
reverse() 方法会直接修改原数组。
语法:
arr.reverse();
sort()
sort() 方法以字母顺序对数组进行排序(默认将所有元素转为字符串再排列)。
sort() 方法很适合字符串,但是在对数值排序时会产生不正确的结果("25"大于"100",因为"2"大于"1")。
sort() 方法会直接修改原数组。
语法:
arr.sort();
多维数组
二维数组
二维数组,即数组中的元素也是数组。
声明
var arr = [
["1001","zhangsan",22],
["1002","lisi",18],
["1003","wangwu",20]
];
// 或者使用关键词 Array(不推荐)
var arr = new Array();
arr[0] = new Array("1001","zhangsan",22);
arr[1] = new Array("1002","lisi",18);
arr[2] = new Array("1003","wangwu",20);
访问或修改数组中的元素,获取数组长度
// 访问
var arr1 = arr[0]; // 访问二维数组中第一个一维数组
var name1 = arr[0][1]; // 访问二维数组中第一个一维数组的第一个元素
// 修改
arr[0][1] = "zhangsanfeng"; // 修改二维数组中第一个一维数组的第一个元素
// 获取长度
var length = arr.length; // 获取二维数组的长度
var arr1_length = arr[0].length; // 获取二维数组中第一个一维数组的长度
遍历二维数组
循环输出二维数组 arr 中的每一个元素:
for(var i = 0;i < arr.length;i++){
for(var j = 0;j < arr[i].length;j++){
console.log(arr[i][j]);
}
}
// for in
for(var i in arr){
for(var j in arr[i]){
console.log(arr[i][j]);
}
}
// for of ( ES6 )
for(let childArr of arr){
for(let v of childArr){
console.log(v);
}
}
实例:二维数组存储杨辉三角
/*
杨辉三角:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
特点:
1、每一行的首尾都是 1。
2、中间数字 = 上一行相同位置的数字 + 上一行相同位置的前一个位置的数字。
*/
var arr = [];
for(let i = 0;i < 10;i++){
arr[i] = [];
for(let j = 0;j <= i;j++){
if(j == 0 || j == i){
arr[i][j] = 1;
}else{
arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
}
}
}