注册 登录

清河洛

javascript中Array数组和Set

qingheluo2016-12-16清河洛496
在JavaScript中,数组不是基本类型,而是具有一定特征的Array对象JavaScript数组是可调整大小的,并且可以包含不同的数据类型必须使用非负整数(或它们各自的字符串形式)作为索引访问通过非整数设置或访问不会设置或从数组列表本身检索元素,但会设置或访问与该数组的对象属性集合相关的变量数组的对象属性和数组元素列表是分开的,数组的遍历和修改操作不能应用于这些命名属性使用方括号表示法而不是点号表示法来访问以数字开头的属性也可以用引号包裹数组下标(如arr['2']),但通常没有必要一个数组本质上就是一个对象,JavaScript引擎通过隐式的将索引数字转化为字符串来获取和保存数组的...

在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)]:数组去重复


网址导航