数组-Array
1.什么是数组
概念
英文:Array 简写 arr
说明:一组【有序】数据的集合
- 数组就是在内存中开辟出一块连续的空间。
- 数组也是一个变量,可以存储一连串的变量/值。
- 数组的大小可以动态的调整,并且没有长度的限制。
- 数组可以存储任意类型的数据。
数组的创建
数组的创建有两种形式:
1.构造函数创建
JS语言提供了一个构造函数:Array(),我我们可以通过该构造函数创建一个数组。(了解)
// 创建一个空数组,括号中没有值,表示创建的数组没有值
var arr1 = new Array();
// 创建一个长度为5的数组,括号中只有一个数字,表示创建的数组的长度
var arr2 = new Array(5);
// 创建一个长度为1的数组,值为'a',括号中只有一个非数字的值,值表示的为数组的值
var arr2 = new Array('a');
//创建一个包含4个元素的数组
var arr3 = new Array(13,43,2,120);
//创建一个包含4个元素的数组
var arr3 = new Array('a','x','z',120);构造函数Array()其实对于我们的使用来说并不友好,因为同一个函数居然有两种行为。这种区别对于新手来说很容易产生混淆,所以我们一般不推荐使用构造函创建数组。
2.字面量创建
我们通常都是更加习惯使用字面量的形式创建数组。 直接使用中括号**"[ ]"**创建即可。
// 创建一个空数组
var nums = [];
//创建一个包含4个元素的数组
var nums = [13,43,2,120];
//创建一个包含4个元素的数组
var nums = [13,'abcd',true,120];数组的索引(下标)
前面我们已经学习了对数组的创建,而我们想要访问数组中数据的话就需要:数组索引。 数组索引:对数组中的数据进行编号,从0开始,依次递增,我们可以通过对数组索引来访问数组中的元素。
// 创建数组
var arr = [];
// 为数组元素赋值, arr[索引]
arr[0] = 12;
arr[1] = 12.5;
arr[2] = 'hello';
// 获取数组元素的值
console.log(arr[0]);// 12
console.log(arr[1]);// 12.5
console.log(arr[2]);// hello上面的代码中我们从索引4直接跳到索引9,那么中间被落下的元素会怎么办呢? 如果数组中元素没有被赋值那么它会有一个默认值:undefined。
数组的遍历
for循环遍历
var arr = [1,2,3];
for(var i=0;i<arr.length;i++){
console.log(arr[i]);// 1,2,3
}for...in循环
for...in中变量item就是数组的索引号
var arr = [1,2,3];
for( var item in arr ){
console.log(item); // 0,1,2
console.log(arr[item]); // 1,2,3
}for...of循环
for...in中变量item就是数组中的每一个值
const arr=[1,2,3]
for(let item of arr){
console.log(item) // 1,2,3
}2.数组的属性
| 属性 | 描述 |
|---|---|
| constructor | 返回创建数组对象的原型函数。 |
| length | 通过arr.length,设置或返回数组元素的个数。 |
| prototype | 允许你向数组对象添加属性或方法。 |
3.数组的原型方法
JS语言为我们提供了一些数组方法,,这些方法使得我们能够很方便的操作数组。
以下是常用的一些数组方法
push()
- 作用:向数组末尾添加一个或多个数据
- 返回值:返回数组新的长度
- 会改变原数组
var arr1 = [123,'abc','hello',true,456];
arr1.push("world");
console.log(arr1); // [123,'abc','hello',true,456,"world"]
var arr2 = [123,'abc','hello',true,456]; console.log(arr2.push("world",789)); // 7pop()
- 作用:删除数组的最后一个数据
- 返回值:并返回被删除的数据
- 会改变原数组
var arr1 = [123,'abc','hello',true,456];
arr1.pop(); console.log(arr1); // [123,'abc','hello',true]
var arr2 = [123,'abc','hello',true,456]; console.log(arr2.pop()); // 456unshift()
- 作用:向数组的开头添加一个或多个数据
- 返回值:并返回数组新的长度
- 会改变原数组
var arr1 = [123,'abc','hello',true,456];
arr1.unshift('美丽',912);
console.log(arr1); // ['美丽',912,123,'abc','hello',true,456]
var arr2 = [123,'abc','hello',true,456];
console.log(arr2.unshift('美丽')); // 6shift()
- 作用:删除数组的第一个数据
- 并返回被删除的数据
- 会改变原数组
var arr1 = [123,'abc','hello',true,456]; arr1.shift();
console.log(arr1); // ['abc','hello',true,456]
var arr2 = [123,'abc','hello',true,456];
console.log(arr2.shift()); // 123sort()
- 作用:默认按字符编码Asc的顺序排列(排列顺序可能会有问题),非string类型会自动转换为string,可自定义比较规则
- 返回值:排序后的数组
- 会改变原数组
var numArr = [23,89,65,33,12,99];
console.log(numArr.sort());升序排序
let arr=[5,2,3,1,5]
arr.sort((a,b)=>{
return a-b
})
console.log(arr) //[1, 2, 3, 5, 5]降序排序
let arr=[5,2,3,1,5]
arr.sort((a,b)=>{
return b-a
})
console.log(arr) //[5, 5, 3, 2, 1]根据数组中指定键排序
const list = [
{
a: 1,
b: 99,
},
{
a: 2,
b: 88,
},
{
a: 3,
b: 77,
},
];
list.sort((a, b) => {
return a.a - b.a ; // 升序排序
// return b.a - a.a; // 降序排序
});
console.log(list);toSorted()
sort()方法的复制版本,用法同sort(),不会改变原数组,返回一个新数组
reverse()
- 作用:将数组元素反转排列
- 返回值:反转后的数组
- 会改变原数组
var arr = [34,'hello',187,'world','sss'];
conso.log(arr.reverse()); // ['sss','world',187,'hello',34]toReversed()
reverse()方法的复制版本,用法同reverse(),不会改变原数组,返回一个新数组
concat()
- 作用:将多个数组拼接成一个数组
- 返回值:拼接后的数组
- 不会改变原数组
var arr1 = [1,2,3,4,5];
var arr2 = ['a','b','c','d','e'];
var arr3 = arr1.concat(arr2);
console.log(arr3); // [1,2,3,4,5,'a','b','c','d','e']slice()
- 作用:截取数组的元素(项)。对数组进行截取,通过传入索引(下标)来实现 截取
- 返回值:被截取的新数组
- 不会改变原数组
1.一个参数
- 表示从这个索引位置开始(包含此索引位置) 一直截取到数组结束
var arr1 = [666,'老铁双击','hello','你好',false,'enne','哈哈哈',true];
console.log(arr1.slice(4)); // [false, 'enne', '哈哈哈', true]2.两个参数
- 第一个参数 表示 开始截取的索引位置(包含此索引位置)
- 第二个参数 表示 结束截取的索引位置(不包含此索引位置)
console.log(arr1.slice(2,6)); // ['hello', '你好', false, 'enne']
console.log(arr1.slice(1,7)); // ['老铁双击', 'hello', '你好', false, 'enne', '哈哈哈']3.第二个参数为负值
- 此时,第一个参数仍为开始截取的索引
- 第二个参数表示从后往前数第几个
- 此刻数组最后一项为-1,依次往前推-2,-3
console.log(arr1.slice(3,-2)); // ['你好', false, 'enne']
console.log(arr1);// [666, '老铁双击', 'hello', '你好', false, 'enne', '哈哈哈', true]splice()
- 作用:向/从数组中删除项目,也可以用作替换操作
- 返回值:被删除的项目组成的新数组
- 会改变原数组
一个参数
表示从这个索引位置开始删除(包含此索引位置),一直删除到数组结束
var arr1 = [12,24,36,47,58,69,70,81,92];
var arr2 = arr1.splice(3);
console.log(arr1); // [12,24,36]
console.log(arr2); // [47,58,69,70,81,92]两个参数
- 第一个参数表示开始删除的索引位置(包含此索引位置)
- 第二个参数表示删除的元素/值的个数
var arr3 = [12,24,36,47,58,69,70,81,92];
var arr4 = arr1.splice(3,5);
console.log(arr3); // [12,24,36,92]
console.log(arr4); // [47,58,69,70,81]三个参数及以上
- 从第三个参数(包括第三个)开始往后,都表示的是要替换被删除的值
var arr5 = [12,24,36,47,58,69,70,81,92];
var arr6 = arr1.splice(3,5,"a");
console.log(arr5); // [12,24,36,"a",92]
console.log(arr6); // [47,58,69,70,81]
var arr7 = [12,24,36,47,58,69,70,81,92];
var arr8 = arr7.splice(3,5,"a",'bb');
console.log(arr7); // [12,24,36,"a",'bb',92]
console.log(arr8); // [47,58,69,70,81]toSpliced()
splice()方法的复制版本,用法同splice(),不会改变原数组,返回一个新数组
toString()
- 作用:toString() 方法可把一个 Number 对象转换为一个字符串,将数组转换为字符串,并以
,隔开 - 返回值:转换成字符串的结果
- 不会改变原数组
var arr1 = [1,'a','2','cc',555];
var arr2 = arr1.toString();
console.log(arr1); // [1, "a", "2", "cc", 555]
console.log(arr2); // 1,a,2,cc,555join()
- 作用:将数组的各项值拼接为字符串
- 返回值:根据传入参数将数组元素拼接的字符串
- 不会改变原数组
不传入参数:直接将数组转换成字符串,并以,隔开
var arr = [1, '2', 3, 'a',true]
console.log(arr.join()); // 1,2,3,a,true传入参数:会根据传入的参数将数组的每一项值进行拼接,传入的值就是拼接的字符
//传入空字符串
console.log(arr.join('')); // 123atrue
//传入其他内容
console.log(arr.join(1)); // 112131a1true
console.log(arr.join('+')); //1+2+3+a+true
console.log(arr.join('你好')); // 1你好2你好3你好a你好trueforEach(fn)
作用:接收一个函数作为参数,对数组的每个数据执行一次给定的函数(和for循环类似)
没有返回值
不会改变原数组
语法:arr.forEach((item,i,arr)=>{})
参数:
- 参数1:数组的各项值;
- 参数2:各项值的下标;
- 参数3:数组本身
var arr = [13,24,35,46];
arr.forEach(function(value,index,arr){
console.log(value,index,arr);
});
// 13 0 [ 13, 24, 35, 46 ]
// 24 1 [ 13, 24, 35, 46 ]
// 35 2 [ 13, 24, 35, 46 ]
// 46 3 [ 13, 24, 35, 46 ]运用forEach()计算数组每一项和
const arr=[1,2,3,4,5]
let sum=0
arr.forEach((item,i)=>{
sum+=item
})
console.log(sum) // 15filter(fn)
作用:参数为一个函数,过滤数组中符合条件的值
返回值:返回一个新数组,把符合条件的值返回(push)到新数组中,新数组和原数组长度不一定相等
不会改变原数组
语法:arr.filter((item,index,arr)=>{})
参数:
- 参数1:数组的值;
- 参数2:值的下标;
- 参数3:数组本身;
var arr1 = [13,24,35,46,57,68,79,80,91];
var arr2 = arr1.filter(function(value,index,arr){
return (value>40);
});
console.log(arr2); // [46,57,68,79,80,91]map(fn)
- 作用:通过指定函数执行数组中的每一项值 ,
- 返回值:返回新的数组,把经过操作的值返回(push)到新数组中
- 不会改变原数组
数组中有几个值就遍历几次,新数组和原数组长度一定相等
var arr1 = [1,2,3,4,5];
var arr2 = arr1.map(function(value,index,arr){
return value+1;
});
console.log(arr2); // [2,3,4,5,6]
var arr3 =arr1.map((item,index)=>{
if(item>=3) return item
})
console.log(arr3); // [undefined,undefined,3,4,5]indexOf()
- 作用:传入的是具体数值,根据数值查找下标
- 返回值:
- 如果存在:返回数组中第一次出现的下标,
- 如果不存在:则返回**-1**。
- 不会改变原数组
var arr1 = [1,2,3,3,3,4,5];
console.log(arr1.indexOf(3)) // 2
console.log(arr1.indexOf('55')) // -1lastIndexOf()
- 作用:查找传入的值在数组中最后一次出现的下标
- 返回值:返回查找值在数组中最后一次出现的下标,如果不存在查找值,则返回**-1**。
- 不会改变原数组
var arr1 = [1,2,3,3,3,4,5];
console.log(arr1.lastIndexOf(3)) // 4
console.log(arr1.lastIndexOf('55')) // -1find()
返回值:返回数组中第一个符合条件的值。否则返回 undefined
不会改变原数组
语法:
array.findIndex(function(item, index, arr), thisValue)参数说明:
| 参数 | 描述 |
|---|---|
| function(item, index,arr) | 必须。数组每个元素需要执行的函数。 |
| thisValue | 可选。 传递给函数的值一般用 "this" 值。 |
| 参数 | 描述 |
|---|---|
| item | 必选。数组遍历的当前项 |
| index | 可选。当前元素的索引 |
| arr | 可选。当前元素所属的数组对象 |
const arr=[1,2,5,9,10]
const res=arr.find(item=>{
return item>5
})
console.log(res)findIndex()
作用:查找对应值的下标
语法:array.findIndex(function(item, index, arr), thisValue)
返回值:返回符合条件的值第一次出现的下标
不会改变原数组
参数说明:
| 参数 | 描述 |
|---|---|
| function(item, index,arr) | 必须。数组每个元素需要执行的函数。 |
| thisValue | 可选。 传递给函数的值一般用 "this" 值。 |
| 参数 | 描述 |
|---|---|
| item | 必选。数组遍历的当前项 |
| index | 可选。当前元素的索引 |
| arr | 可选。当前元素所属的数组对象 |
reduce()
作用:计算数组各项之和
返回值:
不会改变原数组
语法:
arr.reduce((total, item, index, arr)=>{}, initialValue)参数:
- 第一个参数:必选,用于执行每个数组元素的函数。
- 第一个参数:初始值,或者计算结束后的返回值
- 第二个参数:数组当前项
- 第三个参数:当前项下表
- 第四个参数:原数组
- 第二个参数:可选,初始值
计算数组各项之和
const arr=[1,2,3,4,5]
let sum=arr.reduce((total, item, i, arr)=>{
return total+=item
}, 10)
console.log(sum)some()
作用:判断数组中是否有符合条件的值
返回值:若数组中有符合条件的值,返回true,否则返回false
不会改变原数组
参数:
- 参数1:数组的各项值;
- 参数2:各项值的下标;
- 参数3:数组本身
const arr=[1,2,3,4,5]
const res=arr.some((item,index)=>{
return item>3
})
console.log(res) // trueevery()
作用:判断数组中是否全部符合条件的值
返回值:若数组中有符合条件的值,返回true,否则返回false
不会改变原数组
参数:
- 参数1:数组的各项值;
- 参数2:各项值的下标;
- 参数3:数组本身
const arr=[1,2,3,4,5]
const res=arr.every((item,index)=>{
return item<6
})
console.log(res) // flasefill()
作用:将一个固定值替换数组的元素。
会改变原数组
语法:
array.fill(value, start, end)参数:
- value:必须,填充的值
- start:可选,开始填充的下标,包括此下标,默认为0
- end:可选,停止填充下标,不包括此下标,默认为数组的长度
const arr=[1,2,3,4,5,6,7,8,9]
arr.fill('a',2,6)
console.log(arr) // [1,2,'a','a','a','a',7,8,9]若只写第一个参数,则会将数组中所有值都替换
const arr=[1,2,3,4,5,6]
arr.fill(5)
// 相当于 arr.fill('a',0,arr.length)
console.log(arr) // 5,5,5,5,5,54.数组的静态方法
Array.isArray()
判断一个变量是否为数组,返回布尔值
var a=12
console.log(Array.isArray(a)) // false
var arr=[1,2]
console.log(Array.isArray(arr)) // trueArray.form()
作用:from() 方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。
返回值:如果对象是数组返回 true,否则返回 false。
语法:
Array.from(arrayLike, mapFn, thisArg)参数:
- arrayLike:想要转换成数组的类数组或可迭代对象。
- mapFn(item,index):可选,可以通过此回调遍历arrayLike,并返回经过操作的值
- item:数组当前正在处理的元素。
- index:数组当前正在处理的元素的索引。
- thisArg:可选,执行
mapFn时用作this的值。
字符串转数组
var arr = Array.from("Hello");
console.log(arr) // [ 'H', 'e', 'l', 'l', 'o' ]set数据解构转数组
var setObj = new Set(["a", "b", "c"]);
var objArr = Array.from(setObj);
console.log(objArr) // ["a", "b", "c"]使用回调函数
var arr = Array.from([1,2,3],(item,index)=>{
return item+index
});
console.log(arr) // [ 1, 3, 5 ]5.数组的常见算法
数组是JS中最常使用的数据集合之一,所以对它的操作可谓是千奇百怪,有一些操作因为它们的实用性和简易性得到程序员的认可,我们把这些操作叫做数组的算法。
- 常见的数组算法:冒泡排序选择排序数组去重
冒泡排序
冒泡,是因为越大的元素会经由交换慢慢“浮”到数列的顶端,就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
- 那冒泡排序是怎么样式的执行过程呢?接下来看一下: (将大的值冒泡到最后)
var arr = [83,46,17,68,27,99,5]; // 数组
//第一次冒泡 6
// 83 , 46 , 17 , 68 , 27 , 99 , 5 第一个 和 第二个 比 结果 变
// 46 , 83 , 17 , 68 , 27 , 99 , 5 第二个 和 第三个 比 结果 变
// 46 , 17 , 83 , 68 , 27 , 99 , 5 第三个 和 第四个 比 结果 变
// 46 , 17 , 68 , 83 , 27 , 99 , 5 第四个 和 第五个 比 结果 变
// 46 , 17 , 68 , 27 , 83 , 99 , 5 第五个 和 第六个 比 结果 不变
// 46 , 17 , 68 , 27 , 83 , 99 , 5 第六个 和 第七个 比 结果 变
// 46 , 17 , 68 , 27 , 83 , 5 , 99 结束(最大的值已到最后)
//第二次冒泡 5
// 46 , 17 , 68 , 27 , 83 , 5 , 99 第一个 和 第二个 比 结果 变
// 17 , 46 , 68 , 27 , 83 , 5 , 99 第二个 和 第三个 比 结果 不变
// 17 , 46 , 68 , 27 , 83 , 5 , 99 第三个 和 第四个 比 结果 变
// 17 , 46 , 27 , 68 , 83 , 5 , 99 第四个 和 第五个 比 结果 不变
// 17 , 46 , 27 , 68 , 83 , 5 , 99 第五个 和 第六个 比 结果 变
// 17 , 46 , 27 , 68 , 5 , 83 , 99 结束(第二大的值已到到倒数第二的位置)
//第三次冒泡 4
// 17 , 46 , 27 , 68 , 5 , 83 , 99 第一个 和 第二个 比 结果 不变
// 17 , 46 , 27 , 68 , 5 , 83 , 99 第二个 和 第三个 比 结果 变
// 17 , 27 , 46 , 68 , 5 , 83 , 99 第三个 和 第四个 比 结果 不变
// 17 , 27 , 46 , 68 , 5 , 83 , 99 第四个 和 第五个 比 结果 变
// 17 , 27 , 46 , 5 , 68 , 83 , 99 结束(第三大的值已到到倒数第三的位置)
//第四次冒泡 3
// 17 , 27 , 46 , 5 , 68 , 83 , 99 第一个 和 第二个 比 结果 不变
// ......
//第五次冒泡 2
//第六次冒泡 1var arr = [83,46,17,68,27,99,5];
var temp;
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]){
temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
console.log(arr)选择排序
首先从原始数组中找到最小的元素,并把该元素放在数组的最前面,然后再从剩下的元素中寻找最小的元素,放在之前最小元素的后面,直到排序完毕。
var arr = [83,46,17,68,27,99,5];
var temp;
var minIndex;
for(var i=0;i<arr.length-1;i++){
minIndex=i;
for(var j=i+1;j<arr.length;j++){
if(arr[j]<arr[minIndex]){
minIndex=j; }
}
temp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
console.log(arr)数组去重
程序可能会需要一个元素值相对唯一的数组,这样我们就需要将数组中重复的值剔除出去。
var arr = [11,2,2,2,'hello','world','hello'];
var newArr = [];
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i])==-1){
newArr.push(arr[i]);
}
}
console.log(newArr);6.二维数组
概念
二维数组:就是数组的元素也是另一个完整的数组,数组就是作为另一个数组的元素存在的,在JS中其实本质上是不支持二维数组的,但是因为语法的松散性我却是可以实现二维数组的,乃至多维数组。
语法
定义二维数组
var arr = [
[1001,'tom','jack','chris'],
[1002,'apple','orange','tomato'],
[1003,'HTML','CSS','JS'],
];操作:第一个中括号代表操作的是一维、第二个中括号代表操作的二维
arr[2][3]; arr // 这个数组
[2] // 一维中下标为2的值
[3] // 二维中下标为3个值遍历二维数组
遍历二维数组我们需要使用之前学过的双重循环来做最为合适,使用外层循环获得每一个二维数组,使用内存循环获得每一个二维数组里面的元素。
for(var i=0;i<arr.length;i++){
for( var k=0;k<arr[i].length;k++ ){
console.log(arr[i][k]);
}
}7.伪数组
JavaScript中存在一种伪数组,可以使用数组的属性,但不能使用数组的方法
经常见到的伪数组有函数的arguments对象、dom.querySelectorAll获取的节点数组
arguments
在函数被调用时,在函数内部产生,用来接收函数的实参
- 会将函数的所有实参,以数组的形式接收
- arguments对象 是一个 以数组的形式存在的对象,并不是真正的数组,它是一个对象
function addsum() {
console.log(arguments);
// [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6 }
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]); // 1,2,3,4,5,6
}
}
addsum(1, 2, 3, 4, 5, 6);