一、创建数组方法和数组的读取、修改、写入
数组是值的有序集合,其中的值叫作元素。每个元素有一个数值表示的位置,叫作索引,数组中的不同元素可以是不同数据类型。
function demo(){
var arr1=[99,"人","abc",[3,4,5]];
var arr2=[1+1,1>0,"abc"+"123"];
var arr3=[];
var s=JSON.stringify(arr1);//可以看到数组所有值
}
扩展操作符
扩展操作符(…)只能用在数组字面量和一些指定的函数中。扩展操作符可用于任何可迭代对象。
1.展开数组
var arr1=[1,…[45,3,2],100]
var arr2=[…“12232abcba”]
2.解构赋值
var [name,sex,…socre]=[“lily”,“女”,89,96,120]
3.复制数组
var arr3=[9,5,2,7]
var arr4=[…arr3]
Array()构造函数
1.Array()函数构造数组
var arr1=new Array() //创建空数组
var arr2=new Array(3) //创建空数组,指定数组元素个数
var arr3=new Array("3") //创建有1个元素的数组
var arr4=new Array(1,2,5) //创建有3个元素的数组
var arr5=Array.of(3) //创建有1个元素类型为数字的数组
2.构造数组时的数组处理
var arr6=Array.from([..."abc123"]) //将可迭代对象转换为数组
var arr7=Array.from(["Lucass","Lily","Bob"],(v)=>v+"-"+v.length)//对数组的迭代处理
function demo(){
var arr1=new Array();
var arr2=new Array(3);
var arr3=new Array(3,4,5,"a");
var arr4=Array.of(3);
var arr5=Array.from([1,2,6,34],(n)=>n*10);
//等同于var arr5=Array.from([1,2,6,34],function(n){return n*10})
var arr7=Array.from(["Lucass","Lily","Bob"],(v)=>v+"-"+v.length)
}
获取单元格区域
如果读取两个连续及以上的单元格,则可以返回一个二维数组。如果读取的是单行单列则可以将二维数组转换为一维数组
var arr1=Range("a2:a5").Value();//读取单列
var arr1_1=Array.from(arr1,(n)=>n[0]);//单列,转换为一维数组
var arr2=Range("a2:c2").Value();//读取单行
var arr2_1=arr2[0];//单行,转换为一维数组
var arr3=Range("a2:c5").Value();//二维数组
function demo(){
var ar1=Range("a2:a5").Value;//对象
var arr1=Range("a2:a5").Value();//数组
var arr=Array.from(Range("a2:a5").Value(),(v)=>v[0])//单列转一维数组
Console.log(JSON.stringify(arr1));
Console.log(JSON.stringify(arr));
var arr2=Range("a2:c2").Value()[0];//单行转一维数组
Console.log(JSON.stringify(arr2));
var arr3=Range("a2:c5").Value();
Console.log(JSON.stringify(arr3));
}
数组的读取、修改、写入
var arr1=[543,33,99,100];
var arr2=[["Bob",89],["Lucass",80],["Frank",100]];
Console.log(arr1[2]); //读取一维数组的单个值
Console.log(arr2[1][0]); //读取二维数组的单个值
arr1[2]=8888; //修改
arr2[1][0]="ZengXianzhi"; //修改
Range("a1:d1").Value2=arr1; //向单行写入一维数组
Range("a3:a5").Value2=[["北京"],[9000],[30]];//向单列写入二维数组
Range("a7:b9").Value2=arr2; //向多行多列写入二维数组
二、数组元素的添加和删除
push和pop(堆栈:后进先出)
function demo(){
var arr=[122,2,6,99,10];
arr.push(1000,300,600,900,[10,3]);
var a=arr.pop();
//每次只能删除一个,从后面删除,而且删除是从原数组删除,并不是新建一个数组
var b=arr.pop();
var c=arr.pop();
}
unshift和shift(队列:先进先出)
function demo(){
var arr=["aa","bb","cc","dd","ee"];
arr.push(100);
arr.shift();
arr.push(200);
arr.shift();
arr.push(300);
arr.shift();
arr.unshift(12,120,[1,2,3]);
var a=arr.shift();
var b=arr.shift();
arr.unshift(120);
}
splice(添加、删除、替换)
var arr=["a","b","c"]
arr.splice(0,0,"Start"); //在前面插入元素
arr.splice(arr.length,0,"End"); //在后面插入元素
arr.splice(2,0,"Mid"); //在中间插入元素
arr.splice(0,1); //删除前面元素
arr.splice(-1,1); //删除前面元素
arr.splice(1,1); //删除中间元素
arr.splice(1,1,"B") //替换数组元素
应用
筛选二维数组
要求:筛选出年龄大于等于30的记录。
function 筛选(){
let arr=Range("a2:d7").Value();
let arr_new=[["姓名","性别","年龄","籍贯"]]
for (let ar of arr){
if (ar[2]>=30){
arr_new.push(ar);
}
}
Range("f1:i99").ClearContents();
Range("f1").Resize(arr_new.length,4).Value2=arr_new;
}
斐波那契数列
斐波那契数列,又称黄金分割数列,因数学家莱昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”。斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89… 这个数列从第3项开始,每一项都等于前两项之和。
function demo(){
var arr=[0,1]
for (let n=1;n<10;n++){
var v1=arr.pop();
var v2=arr.pop();
var v3=v1+v2;
arr.push(v2,v1,v3);
}
}
就地筛选数组
给定一个一维数组,筛选出大于等于30的数值。
function test(){
var arr=[1,23,76,23,87,1,12,32,31];
let len=arr.length
for (let n=0;n<len;n++){
var v=arr.shift();
if (v>=30){
arr.push(v);
}
}
}
NBA比赛排列
function test(){
var arr=["掘金","灰熊","国王","太阳","快船","勇士","湖人","森林狼"];
var new_arr=[];
while (arr.length>0){
new_arr.push([arr.shift(),arr.pop()]);
console.log(JSON.stringify(new_arr));
}
while (new_arr.length>0){
arr.push([new_arr.shift(),new_arr.pop()]);
console.log(JSON.stringify(arr));
}
}
工资条的生成
function 生成工资条(){
var arr_title=Range("a1:n1").Value()[0];
var arr_null=["","","","","","","","","","","","","",""];
var arr=Range("a2:n16").Value();
var intnum=arr.length-1;
for (let n=intnum;n>=0;n--){
arr.splice(n,0,arr_null,arr_title)
}
Sheets(2).Range("a1").Resize(arr.length,14).Value2=arr;
}
连续数组元素获取(数组切片slice)
var arr=["a","b","c",1,2,3,4,5];
var ar1=arr[0];//单个元素获取
var ar2=arr.slice(2,5);//返回数组(左闭右开)
function test(){
var arr=["a","b","c",1,2,3,4,5];
var ar1=arr[1];
var ar2=arr.slice(1,5);
var ar3=arr.slice(0,1);
}
实例:一维数组转二维数组
function demo1(){
var arr=Array.from(Range("a1:a12").Value(),ar=>ar[0]);
var arr_new=[];
var len=arr.length/3;
for (let n=1;n<=len;n++){
arr_new.push(arr.slice(n*3-3,n*3))
}
Range("c1").Resize(arr_new.length,3).Value2=arr_new;
}
function demo2(){
var arr=Array.from(Range("a1:a12").Value(),ar=>ar[0]);
var len=arr.length/3;
for (let n=1;n<=len;n++){
arr.push([arr.shift(),arr.shift(),arr.shift()])
}
Range("c6").Resize(arr.length,3).Value2=arr;
}
三、数组迭代
数组迭代-1(常规遍历for of)
1.单个变量:for (let x of arr)
2.多个变量:for (let [x,y] of arr)
3.多个变量:for (let [x,y,...z] of arr)
function 求和(){
var arr=Range("a2:e6").Value();
var arr_new=[["姓名","总分"]];
for (let [name,cls,...score] of arr){
arr_new.push([name,WorksheetFunction.Sum(score)]);
}
Range("d10").Resize(arr_new.length,2).Value2=arr_new;
}
数组迭代-2(无返回值forEach)
forEach 是 Array 对象的方法,其作用是对数组的每个元素执行一次提供的函数。和 for of 循环相比,forEach 方法无法使用 break 和 continue 关键字来控制循环流程。
forEach可以遍历数组中的每个元素,并对其执行一个回调函数,不能生成新的数组。回调函数支持三个参数,分别为当前遍历的元素,元素所在的索引,以及正在被遍历的数组。
forEach 可以在遍历过程中修改被遍历的数组。
总体来说,for of 循环适合在遍历数组时需要控制循环流程的场景下使用,而 forEach 则更适合在遍历数组时需要对每个元素执行相同的操作的场景下使用。
function 遍历数组(){
let arr=[43,12,5,234];
arr.forEach(e=>console.log(e));
}
function 修改数组(){
let arr=[43,12,5,234];
arr.forEach((e,i,ar)=>ar[i]=e*10);
}
function 应用(){
let arr=Range("a2:d6").Value();
arr.forEach(([name,...score],i,ar)=>ar[i]=[i+1,name,WorksheetFunction.Sum(score)])
arr.unshift(["序号","姓名","总分"])
Range("a10").Resize(arr.length,3).Value2=arr;
}
数组迭代-3(有返回值map)
map函数与forEach用法相同,不同点在于map可以没有返回值,也可以有返回值。
function 判断当前值是否大于前一个值(){
var arr=[34,3,65,300,2,36];
var n=10
var a=arr.map((e,i,ar)=>{
if (e>ar[i-1]){
return [i+1,e,"√"];
}else{
return [i+1,e,"×"];
}}
)
Console.log(JSON.stringify(a))
Range("a1").Resize(a.length,3).Value2=a;
}
数组迭代-4(筛选filter)
filter()方法返回一个数组,该方法接受的参数应该是一个断言函数,也就是传入的函数应该是返回布尔值true或者false的函数。
function demo(){
var arr=[23,543,23,654,342,62,42];
var arr1=arr.filter(e=>e>=100);
var arr2=arr.filter((e,i,ar)=>e>=ar[i-1]);
}
function 筛选(){
var arr=Range("a2:e11").Value();
var arr_new=arr.filter(([name,id,...score])=>WorksheetFunction.Sum(score)>=380);
arr_new.unshift(["姓名","学号","语文","数学","英语"]);
Range("a13").Resize(arr_new.length,5).Value2=arr_new;
}
数组迭代-5(查找find、findIndex)
find与findIndex都是断言方法,find返回的是值,findIndex返回的是索引,在迭代的过程中,如果有多个元素条件都成立,则只返回第1个。它们的参数同样是需要一个断言函数。find没有匹配成功,返回undefined;findIndex没有匹配成功,返回-1。
function demo1(){
var arr=[32,135,1123,165,34];
var ar1=arr.find((e,i,ar)=>e>=ar[i+1])
var ar2=arr.findIndex((e,i,ar)=>e>=ar[i+1])
}
function demo2(){
var arr=Range("a2:m8").Value();
var n=0;m=0
var arr1=arr.map(([cp,...row])=>[cp,`${1+row.findIndex((e,i,ar)=>{n +=e;if(n>=500){m=n;n=0;return true}})}月`,m]);
arr1.unshift(["产品","月份","达到金额"]);
Range("o1").Resize(arr1.length,3).Value2=arr1;
}
数组迭代-6(与every、或some)
every函数表示数组中所有元素判断后成立则返回true,否则返回false。当判断到第1个元素为false时,则会中断判断,返回false。
some函数表示数组中至少有一个元素判断后成立则返回true,否则返回false。当判断到第1个元素为true时,则会中断判断,返回true。
function demo(){
var arr=Range("b2:m8").Value();
var arr1=arr.map(ar=>[
ar.every(e=>e>=100)?"√":"×",
ar.some(e=>e>=150)?"√":"×",]);
Range("n2").Resize(arr1.length,2).Value2=arr1;
}
数组迭代-7(归并reduce、reduceRight)
reduce是JavaScript中的一个高阶函数,它可以对数组中的每个元素进行累积运算,最终得到一个值。reduce方法接收两个参数:一个回调函数和一个可选的初始值。回调函数接收四个参数:累计值(accumulator)、当前值(currentValue)、当前索引(currentIndex)和数组本身(array)。
下面是reduce方法的语法:
arr.reduce(callback[, initialValue])
其中,callback必需,initialValue可选。
function demo1(){
var arr=[10,2,23,4];
var arr1=arr.reduce((ac,e)=>ac+e,100);
var arr2=arr.reduce((ac,e,i,ar)=>(e>ar[i+1])?ac+1:ac,0);
var arr3=arr.reduce((ac,e)=>{if(e>=10)ac.push(e);return ac},[]);
var arr3=arr.reduceRight((ac,e)=>ac+e);
}
数组迭代-8(reduce方法应用)
案列1:数据累加
function demo1(){
var arr=[2,34,43,11];
arr.reduce((a,e,i,ar)=>ar[i]=a+e)
}
案例2:统计业绩达标月份
function demo2(){
var arr=Range("a2:m8").Value();
var arr1=arr.map(([cp,...val])=>val.reduce((a,e,i)=>(a[2]>500)?a:[cp,i+1,a[2]+e],[,0,0]));
Range("o1").Resize(arr.length+1,3).Value2=[["产品","月份","业绩"]].concat(arr1);
}
四、数组降维
打平函数flat
JavaScript 中的 flat 是一个数组方法,用于将多维数组转换为一维数组。
语法格式为:arr.flat(depth)
其中,depth参数表示要展开嵌套数组的深度,默认值为 1,即只展开一层。如果需要展开所有层级嵌套数组,可以将depth设为 Infinity。
const arr = [1, 2, [3, 4, [5, 6]]];
const flatArr = arr.flat(); // [1, 2, 3, 4, [5, 6]]
const flatArr2 = arr.flat(2); // [1, 2, 3, 4, 5, 6]
const flatArr3 = arr.flat(Infinity); // [1, 2, 3, 4, 5, 6]
需要注意的是,flat方法不会改变原始数组,而是返回一个新的展开后的数组。当然,如果原始数组中有空位,flat 方法会将其删除。
实例:筛选二维数组的元素值,是否大于等于90。
function demo(){
var arr=Range("b2:f9").Value();n=0;
var arr1=arr.flat().filter((e,i)=>e>=90).map(e=>[++n,e]);
arr1.unshift(["序号","销量"]);
Range("h1").Resize(arr1.length,2).Value2=arr1;
}
迭代打平函数flatMap
flatMap() 方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。它等价于在调用 map() 方法后再调用深度为 1 的 flat() 方法(arr.map(…args).flat()),但比分别调用这两个方法稍微更高效一些。
实例:求最高总分
function demo(){
var swf=WorksheetFunction;
var arr=Range("b2:d5").Value();
var arr1=arr.map(row=>[Math.max(...row.flatMap(e=>swf.Sum(e.split("/").map(Number))))]);
Range("e2").Resize(arr1.length,1).Value2=arr1;
}
五、数组连接(concat)
concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
function 合并表格(){
var arr=[["姓名","语文","数学","组别"]];
for (let ws of Sheets){5
var ar=ws.UsedRange.Value();ar.shift();
ar.map(row=>arr.push([].concat(row,ws.Name)))
}
Workbooks.Add().ActiveSheet.Range("a1").Resize(arr.length,4).Value2=arr;
ActiveWorkbook.SaveAs(Workbooks.Item("5-25.xlsm").Path + "\\合并结果.xlsx");
ActiveWorkbook.Close();
}
六、数组合并与字符串拆分(join和split)
join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符字符串分隔。如果数组只有一个元素,那么将返回该元素而不使用分隔符。
split() 方法接受一个模式,通过搜索模式将字符串分割成一个有序的子串列表,将这些子串放入一个数组,并返回该数组。
实例:拆分、筛选、合并
function demo(){
var arr=Range("b2:b4").Value();
var arr1=arr.map(ar=>[ar[0].split("、").filter(e=>Number(e)>=100).join("、")]);
Range("c2").Resize(arr1.length,1).Value2=arr1;
}
七、数组元素查找(indexof和includes)和数组元素排序(sort)
indexOf() 方法返回数组中第一次出现给定元素的下标,如果不存在则返回 -1。
lastIndexOf() 方法返回数组中给定元素最后一次出现的索引,如果不存在则返回 -1。
如果你只需要判断一个元素是否存在于数组中,或者只需要知道该元素在数组中的位置(如果存在),那么 indexOf 是更加简单和直接的选择。
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
var arr=["a","b","c","1","b","a","d","e","d"];
Console.log(arr.indexOf("b"));
Console.log(arr.indexOf("b",2));
Console.log(arr.lastIndexOf("b"));
Console.log(arr.lastIndexOf("b",5));
Console.log(arr.lastIndexOf(1));
Console.log(arr.includes("1"));
JavaScript中的sort()方法是对数组的排序操作。其语法如下:
array.sort([compareFunction])
其中array表示需要排序的数组,compareFunction是一个可选的比较函数。如果未指定compareFunction,则元素将按照字符编码的顺序进行升序排列。
如果指定了compareFunction,则该函数接受两个参数,分别代表要进行比较的两个元素。该函数应当返回一个负数、0或正数,分别代表第一个元素小于、等于、大于第二个元素。
function demo1(){
var arr1=[3,1,65,43,29,200,91];
arr1.sort((a,b)=>b-a);//数字排序
var arr2=[["张三",89],["李四",81],["王麻子",100],["小曾",79]];
arr2.sort((a,b)=>b[1]-a[1]);//数组排序
var arr3=["11月","2月","10月","3月","1月","4月","12月","5月","6月","7月","8月","9月"];
arr3.sort((a,b)=>a.split("月")[0]-b.split("月")[0]);//字符串排序
}
八、5-29数组反转和填充(reverse和fill)
reverse()是数组的一个方法,用于将数组中的元素顺序颠倒过来,并返回已修改后的数组本身。
JavaScript中的fill()方法用于将数组中的所有元素都填充为指定的值。其语法如下:
array.fill(value[, start[, end]])
Var arr = new Array(9).fill(0).map((_,i) =>i+1)
将多个工作表的数据合并。
function 合并表格(){
var arr=[[["姓名","语文","数学","组别"]]];
var zip=ar=>WorksheetFunction.Transpose(ar);
for (let ws of Sheets){
var ar=ws.UsedRange.Value();ar.shift();
var zb=[new Array(ar.length).fill(ws.Name)];
var bb=zip(zip(ar).concat(zb));arr.push(bb);
}
var arr=arr.flat()
Workbooks.Add().ActiveSheet.Range("a1").Resize(arr.length,4).Value2=arr;
ActiveWorkbook.SaveAs(Workbooks.Item("5-30.xlsm").Path + "\\合并结果.xlsx");
ActiveWorkbook.Close();
}