javascript中Array数组和Set
在JavaScript中,数组不是基本类型,而是具有一定特征的Array对象
JavaScript数组是可调整大小的,并且可以包含不同的数据类型
必须使用非负整数(或它们各自的字符串形式)作为索引访问
通过非整数设置或访问不会设置或从数组列表本身检索元素,但会设置或访问与该数组的对象属性集合相关的变量
数组的对象属性和数组元素列表是分开的,数组的遍历和修改操作不能应用于这些命名属性
使用方括号表示法而不是点号表示法来访问以数字开头的属性
也可以用引号包裹数组下标(如arr['2']),但通常没有必要
一个数组本质上就是一个对象,JavaScript引擎通过隐式的将索引数字转化为字符串来获取和保存数组的元素,所以arr[2]和arr[02]两个获取到的值是不同的
arr[2] 获取的是arr.'2'的值
arr[02]获取的是arr.'02'的值
数组的创建
一、使用new关键字new Array(val1,val2,...,valn)
根据根据传入的值创建一个新的数组
当仅传入一个整数num时创建一个每个元素为空的num个元素的数组
进仅传入一个浮点数时会创建失败返回语法错误
var arr = new Array();//创建一个没有任何元素的空数组
var arr = new Array('MyName',20,'zhiye','home');//创建一个数组并分配好元素
var arr = new Array(10);//创建一个包含10个元素的每个元素为空的数组
二、使用Array.of(val1,val2,...,valn)方法
使用传入的值创建一个新的数组
var arr = new Array(10); //创建包含一个元素(10)的数组
三、使用字面量(中括号[])方式
var arr = [1,'2',3]
使用字面量创建数组不会调用Array构造函数
四、Array.from(val,func=None,this_obj=this)方法,将val(可迭代对象或类数组对象)转换为数组
func表示将迭代元素中的每个值再进行一次函数操作
this_obj参数表示再func中的this指向
可迭代对象
let arr = Array.from('12345',x=>x*2);
console.log(arr); // [2, 4, 6, 8, 10]
类数组对象:一个对象如果拥有了length属性,就是一个类数组对象
let arr = Array.from({1: '1',two: 2,3: 3,length: 4});
console.log(arr); // [undefined, '1', undefined, 3]
由于length属性为4,转为的数组元素为4个
只转换了1和3两个属性,其他非数字字符串的属性忽略
将length设为2
let arr = Array.from({1: '1',two: 2,3: 3,length: 2});
console.log(arr); // [undefined, '1']
length属性:数组的长度
arr[arr.length] = 'val';
通过length属性向数组末尾增加一个元素
展开运算符(...)
展开运算符可以把一个数组展开进行操作
//向数组中添加数据
let add = [4, 5, 6];
let now=[1,2,...add,3]
//赋值
let { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 };
console.log(z)// { c: 3, d: 4 }
元素的增删改查操作
push(val1,val2,...,valn):将若干个val添加到数组的最后,返回新数组的长度(改变原数组)
unshift(val1,val2,...,valn):将若干个val添加到数组的开头,返回新数组的长度(改变原数组)
pop():删除数组中最后一个元素,返回被删除的元素(改变原数组),空数组返回undefined
shift():删除数组第一个元素,返回被删除的元素(改变原数组),空数组返回undefined
splice(index, count, val1, val2,...,valn)
从索引index(为负数表示倒数)处删除count个元素
然后插入val1, val2等元素
count不提供则删除至数组末尾
返回被删除的元素组成的新数组(改变原数组)
concat(val1,val2,...,valn):功能和push()相似,都是将新元素添加到数组末尾,不同的是
val可以为数组,如果为数组则将数组展开依次添加
返回新数组(不改变原数组)
fill(val,start_index=0,end_index=None):将索引指定范围中所有元素都替换为val
copyWithin(target,start,end):截取数组中从start开始到end(不含)然后从target位置开始替换原数组
at(index):根据索引获取值
查找数组元素
includes(val,start_index=0):从start_index向后搜索数组中是否含有val值
indexOf(val):返回数组中从前向后查找的第一个val元素的索引,没有该元素则返回-1(不改变原数组)
lastIndexOf(val):返回数组中从后向前查找的第一个val元素的索引,没有该元素则返回-1(不改变原数组)
find(func)
返回数组中第一个传入func返回true的元素值
func返回true后停止后续调用
func接受三个参数,第一个为必需,后两个为可选参数
第一个为当前的值
第二个为当前的索引
第三个为当前元素所属的数组对象
findIndex(func):同find(),返回元素的索引值
findLast():同find(),从后向前依次遍历
findLastIndex():同findIndex(),从后向前依次遍历
数组的截取
slice(start, end):截取原数组索引start开始到索引end结束,不包含end,返回获取的子数组(不改变原数组),负数表示倒数第几位
数组的顺序变动
reverse():反转数组,返回反转后的新数组(改变原数组)
sort([func]):对数组元素进行从大到小排序,返回排序后的新数组(改变原数组)
这里的排序并不是按值排序,而是先将所有元素全部转换为字符串
然后依次根据每个字符对应的ASCII码值进行排序
a = [31, 22, 27, 1, 9];
a.sort();
console.log(a); // [1, 22, 27, 31, 9]
该函数还可以接受一个函数,函数接受两个参数,表示依次递归的将数组中的元素传入
如果函数返回正数则按原顺序排序
如果函数返回负数则交换这两个元素的位置
a = [31, 22, 27, 1, 9];
a.sort((a, b) => a-b); //按数值大小正序排列
console.log(a); // [1, 9, 22, 27, 31]
数组转换为字符串
join(val):将数组用val连接为字符串,返回被连接后的字符串(不改变原数组),val默认为逗号(,)
val为对象时先对对象使用toString()获取字符串,然后使用该字符串连接元组
toString():将数组中的元素用逗号拼接成字符串,返回拼接后的字符串(不改变原数组)
toLocaleString():根据当前本地环境来返回字符串,数组对象使用时和toString()没有区别
但是其他有具体语义的对象类型使用时会有区别,如:
对数字使用,会添加千位分隔符,6666会转换为'6,666'
对日期对象使用会转换为中文
let now = new Date();
now.toLocaleString() //'2022/11/25 09:02:15'
now.toString() //'Fri Nov 25 2022 09:02:15 GMT+0800 (中国标准时间)'
在一些比较严格的环境中我们必须使用toString(),因为这样能保证无论在那个环境中使用返回的结果都时相同的
遍历循环
entries():返回一个迭代器,用于遍历数组的键值对
keys():返回一个迭代器,用于遍历数组的索引
values():返回一个迭代器,用于遍历数组的值
forEach(func)
遍历数组中每一项传递给函数并运行函数
函数默认3个参数分别为:元素内容、元素索引、数组本身
没有返回值
map(func):
遍历数组中每一项传递给函数并运行函数
函数默认3个参数分别为:元素内容、元素索引、数组本身
返回函数分别传入每个元素后的返回值组成的新数组
filter(func):数组过滤
遍历数组中每一项传递给函数并运行函数
函数默认3个参数分别为:元素内容、元素索引、数组本身
返回函数分别传入每个元素后的返回值为true的元组组成的新数组
every(func):判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true
遍历数组中每一项传递给函数并运行函数
函数默认3个参数分别为:元素内容、元素索引、数组本身
如果函数分别传入每个元素后的返回值全部为true,则返回true,否则返回false
some():
遍历数组中每一项传递给函数并运行函数
函数默认3个参数分别为:元素内容、元素索引、数组本身
如果函数分别传入每个元素后的返回值只要有一个为true,则返回true,否则返回false
reduce(func[,initval]):接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
对数组的元素进行递归调用,最终返回一个值
函数接受4个参数int,val,index,arr)
init表示初始值,如果提供了initval,则第一次运行时init为该值,val为数组第一个元素
如果没有提供initval,则第一次运行时init为数组的第一个元素,val为数组第二个元素
每次运行都会将上一次的函数返回值赋值给init参数,val为数组的下一个元素,如此循环,直至将数组完整遍历
返回函数最后依次运行后的返回值
arr1 = [1,2,3,4,5]
arr2 = ['a','b','c','d']
res1 = arr1.reduce((init,val,index,arr1)=>init+val);
console.log(res1); //15
res2 = arr2.reduce((init,val,index,arr)=>init+val,'s');
console.log(res2); //sabcd
reduce()对于空数组是不会执行回调函数的
数组的降维操作
flat(n=1),对数组进行降维操作(嵌套数组转为一维数组)
传入一个数字表示转换的层数,最外层数组层数为0
传入Infinity,则全部层都进行转换
将元素放置到第一层时会自动跳过为空的元素
[1, [2, [3, [4, ,5]]]].flat() // [1, 2, [3, [4,empty,5]]]
[1, [2, [3, [4, ,5]]]].flat(2) // [1, 2, 3, [4,empty,5]]
[1, [2, [3, [4, ,5]]]].flat(Infinity) // [1, 2, 3, 4, 5]
flatMap(func,this_obj)
先对数组进行map处理,再对处理后的新数组进行降维操作(仅能操作一层嵌套)
func接受两个参数,当前值、当前索引
可选参数this_obj是定func中的this指向
Set数据结构
ES6提供了新的数据结构 Set,它类似于数组,但是成员的值都是唯一的
Set内部判断成员是否相同使用的是类似于精确相等运算符(===),唯一不同的是Set认为NaN等于自身
Set( [iterable] )构造函数用来创建Set数据结构
可以接受一个具有iterable(迭代器)接口的任何数据结构作为参数,用来初始化
let s = new Set([1,2,3]); // 使用数组初始化
let d = new Set(s); // 使用Set初始化
Array.from(Set)用于将Set转换为数组
Array.from(new Set(arr)):数组去重复
Set实例的属性和方法
size :返回成员总数
add(val):添加成员,返回更新后的Set
由于返回的是更新后的Set,该方法可以链式调用
delete(val) :删除成员,返回删除是否成功的布尔值
has(val):判断是否存在某个值
clear():清除所有成员,没有返回值
values():返回键值遍历器
keys():返回键名遍历器
Set没有键名,或者说键名和键值是同一个值
所以keys方法和values方法的行为完全一致
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
Set可以用for...of循环遍历
Set可以用...展开运算符
[...new Set(arr)]:数组去重复