数组
1.概念
-
数组构成: 数组由一个或多个数组元素组成的,各元素之间使用逗号“,”分割。
-
数组元素:每个数组元素由“下标”和“值”构成。
下标:又称索引,以数字表示,默认从O开始依次递增,用于识别元素。
值:元素的内容,可以是任意类型的数据,如数值型、字符型、数组、对象等。
2.创建
实例化Array对象的方式:
实例化Array对象的方式创建数组,是通过new关键字实现的。
<script>
// 元素值类型为字符型
var area = new Array('Beijing', 'Shanghai', 'Shenzhen');
// 元素值类型为数值型
var score = new Array(56, 68, 98, 44);
// 元素值类型为混合型
var mix = new Array(123, 'abc', null, true, undefined);
// 空数组
var arr1 = new Array(); // 或 var arr2 = new Array;
</script>
直接使用“[ ]”的方式:
直接法“”与Array()对象的使用方式类似,只需将new Array()替换为即可。
<script>
var weather = ['wind', 'fine',]; // 相当于:new Array('wind', 'fine',)
var empty = []; // 相当于:new Array
var mood = ['sad', , , ,'happy']; // 控制台输出mood:(5) ["sad", empty × 3, "happy"]
</script>
注意:
在创建数组时,最后一个元素后的逗号可以存在,也可以省略。
直接法“”与Array()对象在创建数组时的区别在于,前者可以创建含有空存储位置的数组,而后者不可以。如:var mood = ['sad', , , ,'happy'];
3.基本操作
Array的length属性
获取长度
其值为数组元素最大下标加1。
<script>
var arr1 = [78, 88, 98];
var arr2 = ['a', , , , 'b', 'c'];
console.log(arr1.length); // 输出结果为:3
console.log(arr2.length); // 输出结果为:6
</script>
数组arr2中没有值的数组元素会占用空的存储位置。因此,数组的下标依然会递增。从而arr2调用length属性最后的输出结果即为6。
修改长度
①若length的值大于数组中原来的元素个数,则没有值的数组元素会占用空存储位置。
②若length的值等于数组中原来的元素个数,数组长度不变。
③若length的值小于数组中原来的元素个数,多余的数组元素将会被舍弃。
<script>
var arr1 = [];
arr1.length = 5;
console.log(arr1); // 输出结果:(5) [empty × 5]
var arr2 = [1, 2, 3];
arr2.length = 4;
console.log(arr2); // 输出结果:(4) [1, 2, 3, empty]
var arr3 = ['a', 'b'];
arr3.length = 2;
console.log(arr3); // 输出结果:(2) ["a", "b"]
var arr4 = ['hehe', 'xixi', 'gugu', 'jiujiu'];
arr4.length = 3;
console.log(arr4); // 输出结果:(3) ["hehe", "xixi", "gugu"
</script>
指定长度
利用Array对象。
<script>
var arr = new Array(3);
console.log(arr); // 输出结果:(3) [empty × 3]
</script>
访问元素
数组元素访问方式:“数组名下标”。
<script>
var arr = ['hello', 'JavaScript', 22.48, true];
console.log(arr[0]);
console.log(arr[2]);
console.log(arr);
</script>
遍历元素
概念:所谓遍历数组就是依次访问数组中所有元素的操作。
利用下标遍历数组可以使用: for / for…in语句 / for…of语句
for (variable in object){...}
for…in中的variable指的是数组下标。
for…in中的object表示数组的变量名称。
除此之外,若object是一个对象,for…in还可以用于对象的遍历。
<div class="nav" id="navlist"></div>
<script>
var navlist = ['首页', '免费资源', '课程中心', 'IT学院', '学员故事', '线上学院', '技术社区'];
var str = '<ul>';
for (var i in navlist) {
str += '<li><a>' + navlist[i] + '</a></li>';
}
str += '</ul>';
document.getElementById('navlist').innerHTML = str;
</script>
效果如图
<script>
var arr = [1, 2, 3];
for (var value of arr) { //for..of语句
console.log(value);
}
</script>
变量value:表示每次遍历时对应的数组元素的值。
变量arr:表示待遍历的数组。
结果:在控制台中依次输出1、2和3。
添加元素
添加数组元素:数组名[下标]=值。
允许下标不按照数字顺序连续添加,未设置具体值的元素,会以空存储位置的形式存在。
数组中元素保存顺序与下标有关,与添加元素的顺序无关。
<script>
// 为空数组添加元素
var height = [];
height[5] = 183;
height[0] = 175;
height[3] = 150;
console.log(height); // 输出结果:(6) [175, empty × 2, 150, empty, 183]
// 为非空数组添加元素
var arr = ['Asa', 'Taylor'];
arr[2] = 'Tom';
arr[3] = 'Jack';
console.log(arr); // 输出结果:(4) ["Asa", "Taylor", "Tom", "Jack"]
</script>
- 修改元素
修改元素与添加元素的使用相同,区别在于修改元素是为已含有值的元素重新赋值。
<script>
var arr = ['a', 'b', 'c', 'd'];
arr[2] = 123;
arr[3] = 456;
console.log(arr); // 输出结果:(4) ["a", "b", 123, 456]
</script>
元素删除
delete关键字只能删除数组中指定下标的元素值,删除后该元素依然会占用一个空的存储位置。
<script>
var stu = ['Tom', 'Jimmy', 'Lucy'];
console.log(stu); // 输出结果:(3) ["Tom", "Jimmy", "Lucy"]
delete stu[1]; // 删除数组中第2个元素
console.log(stu); // 输出结果:(3) ["Tom", empty, "Lucy"]
</script>
解构赋值
例如,若把数组[1,2.3]中的元素分别赋值为a、b和c,传统的做法是单独为变量声明和赋值。
<script>
// 传统方式
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
//解构赋值方式
[a,b,c]=[1,2,3];
</script>
<script>
var arr = [1, 2, 3];
[a, b] = arr;
console.log(a + ' - ' + b); // 输出结果:1 - 2
var n1 = 4, n2 = 8;
[n1, n2] = [n2, n1];
console.log(n1 + ' - ' + n2); // 输出结果:8 - 4
</script>
【案例】javascript查找最大值与最小值
代码实现思路:假设法
①假设待查找数组的第一个
③在遍历数组时,判断当前元素是否大于max,若大于,修改max值。
④同理,在遍历数组时,判断当前元素是否小于min,若小于,修改min值。
<script>
var arr = [100, 7, 65, 54, 12, 6]; // 待查找数组
var min = max = arr[0]; // 假设第1个元素为最大值和最小值
for (var i = 1; i < arr.length; ++i) {
if (arr[i] > max) { // 当前元素比最大值max大,则修改最大值
max = arr[i];
}
if (arr[i] < min) { // 当前元素比最小值min小,则修改最小值
min = arr[i];
}
}
console.log('待查找数组:' + arr);
console.log('最小值:' + min);
console.log('最大值:' + max);
</script>
4. 二维数组操作
创建
<script>
// 使用Array对象创建数组
var info = new Array(new Array('Tom', 13, 155), new Array('Lucy', 11, 152));
var arr = new Array(new Array, new Array); // 空二维数组
// 使用“[]”创建数组
var num = [[1, 3], [2, 4]];
var empty = [[], []];
</script>
遍历
二维数组只需在遍历数组后,再次遍历数组的元素即可。
<script>
var arr = []; // 创建一维空数组
for (var i = 0; i < 3; ++i) {
arr[i] = []; // 将当前元素设置为数组
arr[i][0] = i; // 为二维数组元素赋值
}
</script>
若要为二维数组元素(如arr[i][0]
)赋值,首先要保证添加的元素(如arr[])已经
被创建为数组,否则程序会报“Uncaught TypeError…”错误。
【案例】javascript二维数组转置
二维数组的转置指的是将二维数组横向元素保存为纵向元素。
代码实现思路:
①找规律:res[0][0]
= arr[0][0]
、res[0][1]
= arr[1][0]
、res[0][2]
= arr[2][0]
。
②得结论:res[i][j]
= arr[j][i]
。
res数组长度=arr元素(如arr[0])的长度。
res元素(如res[0])的长度=arr数组的长度。
⑤按照③和④完成res的创建与遍历,按②进行转置。
<script>
var arr = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['j', 'k', 'l']];
var res = [];
for (var i = 0; i < arr[0].length; ++i) { // 遍历res中的所有元素
res[i] = [];
for(var j = 0; j < arr.length; ++j){ // 遍历res元素中的所有元素
res[i][j] = arr[j][i]; // 为二维数组赋值
}
}
console.group('转置前:');
console.log(arr);
console.groupEnd();
console.group('转置后:');
console.log(res);
console.groupEnd();
</script>
5. 数组排序
冒泡排序
插入排序
插入排序: 是冒泡排序的优化,也是一种直观的简单排序算法。
实现原理: 通过构建有序数组元素的存储,对于未排序的数组元素,在已排序的数组中从最后一个元素向第一个元素遍历,找到相应位置并插入。
其中,待排序数组的第1个元素会被看作是一个有序的数组,从第2个至最后一个元素会被看作是一个无序数组。
6.常见数组方法
栈和队列方法
JavaScript中,除了前面讲解的添加与删除数组元素的方式外,还可以利用Array对象提供的方法,模拟栈和队列的操作。
- 在数组的末尾或开头添加数组的新元素。
- 在数组的末尾或开头删除数组元素。
push()和unshift()方法的返回值是新数组的长度。
pop()和shift()方法返回的是移出的数组元素。
检索方法
在开发中,若要检测给定的值是否是数组,或是查找指定的元素在数组中的位置。
表中除了Array.isArray()方法外,其余方法默认都是从指定数组索引的位置开始检索,且检索方式与运算符“===”相同,即只有全等时才会返回比较成功的结果。
- includes()方法的第1个参数表示待查找的值。
- includes()方法的第2个参数用于指定在数组中查找的下标。
·设置为大于数组长度时,数组不会被检索,直接返回false。
·设置为小于0的数时,则检索的索引位置等于数组长度加上指定的负数,若结果
仍是小于0的数,则检索整个数组。
【案例】includes()
用于确定数组中是否含有某个元素,含有返回true,否则返回falseo
【案例】Array.isArray()
用于确定传递的值是否是一个Array,是返回true,不是返回false。
<script>
var data = ['peach', 'pear', 26, '26', 'grape'];
// 从数组下标为3的位置开始检索数字26
console.log(data.includes(26, 3)); // 输出结果:false
// 从数组下标为data.length - 3 的位置查找数字26
console.log(data.includes(26, -3)); // 输出结果:true
// 判断变量data是否为数组
console.log(Array.isArray(data)); // 输出结果:true
</script>
【案例】indexOf()
返回在数组中可以找到给定值的第一个索引,如果不存在,则返回-1
<script>
var arr = ['potato', 'tomato', 'chillies', 'green-pepper'];
var search = 'cucumber';
if (arr.indexOf(search) === -1) { // 查找的元素不存在
arr.push(search);
console.log('更新后的数组为: ' + arr);
} else if (arr.indexOf(search) > -1) { // 防止返回的下标为0,if判断为false
console.log(search + '元素已在arr数组中。');
}
</script>
【案例】lastIndexOf()
返回指定元素在数组中的最后一个的索引,如果不存在则返回-1
<script>
var res = [];
var arr = ['a', 'b', 'a', 'c', 'a', 'd']; // 待检索的数组
var search = 'a'; // 要查找的数组元素
var i = arr.lastIndexOf(search);
while (i !== -1) {
res.push(i);
i = (i > 0 ? arr.lastIndexOf(search, i - 1) : -1);
}
console.log('元素 ' + search + ' 在数组中的所有位置为:' + res);
</script>
数组转字符串
开发中若需要将数组转换为字符串时,则可以利用JavaScript提供的方法实现。
join()和toString()方法的相同点:
1.可将多维数组转为字符串,默认情况下使用逗号连接。
2.当数组元素为undefined、null或空数组时,对应的元素会被转换为空字符串
join()和toString()方法的不同点:
1.join()方法可以指定连接数组元素的符号。
<script>
console.log(['a', 'b', 'c'].join()); // 输出结果:a,b,c
console.log([[4, 5], [1, 2]].join('-')); // 输出结果:4,5-1,2
console.log(['a', 'b', 'c'].toString()); // 输出结果:a,b,c
console.log([[4, 5], [1, 2]].toString()); // 输出结果:4,5,1,2
</script>
其他方法
除了前面的几种常用方法外,JavaScript还提供了很多其他常用的数组方法。
例如,合并数组、数组浅拷贝、颠倒数组元素的顺序等。
- slice()和concat()方法在执行后返回一个新的数组,不会对原数组产生影响,其他方法在执行后皆对原数组产生影响。
- splice()方法的第1个参数的值等于或大于数组长度时,从数组末尾开始操作;当该值为负数时,则下标位置等于数组长度加上指定的负数,若其值仍为负数,则从数组的开头开始操作。
<script>
var arr = ['sky', 'wind', 'snow', 'sun'];
// 从数组下标2的位置开始,删除2个元素
arr.splice(2, 2);
console.log(arr);
// 从数组下标1的位置开始,删除1个元素后,再添加snow元素
arr.splice(1, 1, 'snow');
console.log(arr);
// 指定下标4大于数组的长度,则直接在数组末尾添加hail和sun元素
arr.splice(4, 0, 'hail', 'sun');
console.log(arr);
// 从数组下标3的位置开始,添加数组、null、undefined和空数组
arr.splice(3, 0, ['lala', 'yaya'], null, undefined, []);
console.log(arr);
</script>
【案例】JavaScript猴子选大王**
游戏规则: 要求一群猴子排成一圈,按“1,2,…,n”依次编号。然后从第1只开始数,数到第m只,把它踢出圈,其后的猴子再从1开始数,数到第m只,再把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就是我们要找的大王。
代码实现思路:
①通过prompt()接收用户传递的猴子总数n和踢出的第m只猴子。
②利用数组保存所有猴子的编号(1~n)。
③设置一个变量i,记录每次参与游戏(报数)的猴子位置。
④通过while循环,只要猴子数组内元素个数大于1,就继续循环。
⑤在循环中判断当前猴子的位置i与m求余是否为0,若为零,删除该数组元素。
提示:通过出栈的方式取出猴子,如判断不为0,再将该元素入栈。
<script>
var total = prompt('请输入猴子的总数');
var kick = prompt('踢出第几只猴子');
var monkey = [];
for (var i = 1; i <= total; ++i) { // 创建猴子数组
monkey.push(i);
}
i = 0; // 记录每次参与游戏(报数)的猴子位置
while (monkey.length > 1) { // 在猴子数量大于1时进行循环
++i;
head = monkey.shift(); // 从monkey数组的开头,取出猴子
if (i % kick != 0) { // 判断是否踢出猴子,不踢则把该猴子添加到monkey数组的尾部
monkey.push(head);
}
}
console.log('猴王编号:' + monkey[0]);
</script>
【案例】JavaScript省份城市的三级联动 ***
代码实现思路:
创建HTML表单,实现省份、城市、区域的下拉列表。
创建数组保存省份城市区域的数据。
③编写函数createOption()用于创建指定下拉菜单的选项。
④选择省份后,显示对应城市菜单(利用onchange事件)。
⑤选择城市后,显示对应区域菜单(利用onchange事件)。
⑥修改省份后,更新城市和区域下拉菜单。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>省份城市的三级联动</title>
</head>
<body>
<form>
<select id="province">
<option value="-1">请选择</option>
</select>
<select id="city"></select>
<select id="country"></select>
</form>
<script>
// 省份数组
var provinceArr = ['上海', '江苏', '河北'];
// 城市数组
var cityArr = [
['上海市'],
['苏州市', '南京市', '扬州市'],
['石家庄', '秦皇岛', '张家口']
];
// 区域数组
var countryArr = [
[
['黄浦区', '静安区', '长宁区', '浦东区']
], [
['虎丘区', '吴中区', '相城区', '姑苏区', '吴江区'],
['玄武区', '秦淮区', '建邺区', '鼓楼区', '浦口区'],
['邗江区', '广陵区', '江都区']
], [
['长安区', '桥西区', '新华区', '井陉矿区'],
['海港区', '山海关区', '北戴河区', '抚宁区'],
['桥东区', '桥西区', '宣化区', '下花园区']
]
];
// 第1步
function createOption(obj, data) {
for (var i in data) {
var op = new Option(data[i], i); // 创建下拉列表中的option选项
obj.options.add(op); // 将选项添加到下拉列表中
}
}
var province = document.getElementById('province');
createOption(province, provinceArr);
// 第2步
var city = document.getElementById('city');
province.onchange = function() {
city.options.length = 0; // 清空city下的原有<option>
createOption(city, cityArr[province.value]);
if (province.value >= 0) {
city.onchange(); // 自动添加 城市对应区域 下拉列表
} else {
country.options.length = 0; // 清空country下的原有<option>
}
};
// 第3步
var country = document.getElementById('country');
city.onchange = function() {
country.options.length = 0; // 清空country下的所有原有<option>
createOption(country, countryArr[province.value][city.value]);
};
</script>
</body>
</html>