一、创建数组 x=[ ]
let a=["333","999"]; // 直接写在[ ]中
let aa=new Array(4,8,9); // 通过实例传入Array中
let aaa=new Array(5); // 传入的5为array的个数
aaa[0]=6; // 给aaa的第0个赋值为6
console.log(aaa); // [6,,,,,]
console.log(aa); // [4,8,9]
复制代码
二、 访问数组元素 x.[index]
let a=["333","999"];
let b=a[0]; // 访问数组的第一个元素
let c=a[a.length-1]; // 访问数组的最后一个元素
let f=a["1"]===a[1]; // a["1"]会自动转为数字1
console.log(f); // true
复制代码
当然,如果我们通过以下方式去访问时,会被解析成连续运算返回最后一个值
console.log([2,3,4,5][1,2]) // 4
复制代码
数组也是一种特殊的对象,因此我们也可以通过键值对的形式去访问
let arr9 = [];
arr9.say = 'Hello';
console.log(arr9.say) // Hello
复制代码
三、遍历数组 x.forEach(function(item,index,array){})
es6写法 forEach((item,index)=>{dosomething.....})
let a=["333","999"];
a.forEach(function (item,index,array) {
console.log(item,index)
});
//333 0 999 1
复制代码
四、添加元素到数组的末尾 x.push(...)
let a=["333","999"];
a.push("我是新元素","666");
console.log(a); //["333","999","我是新元素","666"]
console.log(a.push("我","690"),a.length,a); //6,["333","666","我是新元素","666","我","690"]
//返回新数组长度6,会执行一次a.push
复制代码
五、在末尾删除数组(只能删除1个) x.pop()
let a=["333","999"];
a.pop();
console.log(a); // ["333"]; 返回新数组
console.log( a.pop(),a); //333 []
//会执行一次a.pop(),返回本次被删除元素
复制代码
六、删除数组最前面元素 x.shift()
let a=["333","999"];
a.shift();
console.log(a); // ["999"]
console.log( a.shift()); // "999"
//返回被删除元素,不会执行a.shift()
复制代码
七、添加到数组的前面(头部)x.unshift("...")
let a=["333","999"];
a.unshift("000","888","777");
console.log(a);
// ["000","888","777","333","999"]
console.log(a.unshift("111"),a.length,a);
//["111","000","888","777","333","999"]
//会执行一次a.unshift,返回数组长度,
复制代码
八、找到某个元素在数组中的索引 indexOf
let a=["333","999"];
let d=a.indexOf("333"); // 通过元素查找在当前数组的索引值
console.log(d); // 0
let e=a.indexOf("654"); // 如果查不到返回-1
console.log(e); // -1
复制代码
九、数组浅拷贝 slice()
, Array.from()
,[...]
let a=[1,2,8];
let newArray=a.slice();
console.log(newArray); //第一种方法 [1,2,8]
-----------------------------------
let newArray2=Array.from(a);
console.log(newArray2); //第二种方法 [1,2,8]
------------------------------------
let newArray3=[...a];
console.log(newArray3); //第三种方法 [1,2,8]
复制代码
十、清空数组
// 两种方法都可以实现,但第二种比较优雅
let arr=[1,2,3,3,4,5];
arr=[];
console.log(arr) // []
------------------------------------
let arr=[888,99];
arr.length=0;
console.log(arr) // []
复制代码
十一、合并数组
let arr=[1];
let arr2=[2];
let arr3=[3];
let arr4=arr.concat(arr2,arr3)
console.log(arr4) // [1,2,3]
---------------------------------------
// 下面这个方法也可以实现,但只能合并两个数组
let arr1=[1,2,3];
let arr2=[4,5,6];
arr1.push.apply(arr1,arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
-------------------------------------
// ES6的数组合并:
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
[...arr1, ...arr2, ...arr3]; // [ 'a', 'b', 'c', 'd', 'e' ]
复制代码
十二、在数组中找到最大值和最小值
//方法1
let array1 = [1,2,3,4];
let array2 = Math.max.apply(null,array1); // 最大值
let array3 = Math.min.apply(null,array1); // 最小值
console.log(array2,array3); // 4 ,1
--------------------------------------------------
//方法2
let array4 =Math.max(...array1); // 最大值
let array5 =Math.min(...array1); // 最小值
console.log(array4,array5); // 4 ,1
复制代码
十三、判断是不是数组
// 在javascript中,如何判断一个变量是否是数组
(1)Array.isArray()方法
var a = [0, 1, 2];
console.log(Array.isArray(a)); // true
(2)typeof toString 方法
复制代码
由于低版本的IE
不支持ES5
,如需要兼容,用typeof
,我们都知道,数组是特殊的对象,所以数组的typeof
结果也是object
,而因为null
的结果也是object
,所以需要加判断是 object
同时排除null
、排除纯对象,先判断a
是不是object
,并且a!==null
, 并且toString.call
判断a
等于 [object Array]
let a = [0, 1, 2];
console.log( typeof a ==='object' && a !==null && Object.prototype.toString.call(a) ==='[object Array]'); // true
复制代码
十四、数组与其他值的运算(使用"+"会自动转为string
,"-"会自动转为number
)
// 数组和任何值相加都会将数组转换成字符串再进行拼接
console.log([1,2,3] + 6) ; // "1,2,36"
console.log([1,2,3] + {}) ; // "1,2,3[object Object]"
console.log([1,2,3] + [1,2,3]); // "1,2,31,2,3"
如果数组只有一个值,那么当这个数组和其他值相减相乘等时会被转换为数字,如果为空会被转换为0
console.log([5] - 2) // 3
复制代码
十五、数组去重
// ES6新增的Set数据结构,类似于数组,但是里面的元素都是唯一的,其构造函数可以接受一个数组作为参数
let arr1=[1,2,1,2,6,3,5,69,66,7,2,1,4,3,6,8,9663,8]
let set = new Set(arr1);
console.log(set) // [ 1,2,6,3,5,69,66,7,4,8,9663,8]
复制代码
十六、将数组顺序打乱
let arr = [1,2,3,4,5,6];
function upsetArr(arr){
return arr.sort(function(){ return Math.random() - 0.5});
}
upsetArr(arr) ; // [4, 1, 3, 2, 5, 6]
复制代码
解析:沿用原
sort
的a-b的方法,先生成一个随机数,然后将其与随机数进行 比较,如果Math.random() - 0.5是true,则返回前者,否则比较下一个
十七 实现将数组中数字求和,字母忽略。
let arr= ["a",3,4,5,9,"d"];
function sum (arr){
let a=0;
for(let i=0;i<arr.length;i++){
if(typeof arr[i]==="number"){
a+=arr[i]
}
}
return a;
}
sum(arr) //21
复制代码
通过循环遍历判断数组中的每个值是否是数字,如果是的赋值到变量上进行加法计算
十八、delete
,splice
删除数组内指定的某个值。
使用
delete
删除数组内的制定索引的值后,直接改的是原数组,而且删除值的位置仍然保留,为undefined
。
let arr=[1,2,3,45,5,2];
delete arr[0]
console.log(arr,arr[0]). // [empty,2,3,45,5],undefined
复制代码
如果要彻底删除,可以使用
splice()
方法splice(开始位置,删除个数,添加的值)
,如果没有第三个值,可以只传前两个值
两个值的示例:
let arr=[1,2,3,45,5,2];
arr.splice(0,1)
console.log(arr) // [2, 3, 45, 5, 2]
复制代码
三个值的示例:
let arr=[1,2,3,45,5,2];
arr.splice(0,1,100)
console.log(arr) // [100 ,2, 3, 45, 5, 2]
复制代码
十九、slice()
截取数组,可选择开始位置和结束位置
Array.slice(begin,end) 接收两个参数,第一个是开始位置,第二个是结束位置
拷贝开始位置到结束位置,前包后不包
如果
end
被省略,则slice
会一直提取到原数组末尾。
如果
end
大于数组的长度,slice
也会一直提取到原数组末尾
let arr=[1,2,3,45,5,2];
let arr1 = arr.slice(0,4)
console.log(arr1). // [1, 2, 3, 45]
复制代码
如果slice()
括号中不传参数,将会全部截取,即实现浅拷贝
let arr=[1,2,3,45,5,2];
let arr1 = arr.slice()
console.log(arr1). // [1, 2, 3, 45, 5, 2]
复制代码
二十、颠倒数组的顺序,也称数组的反转
let arr=[1,2,3,45,5,2];
arr.reverse()
console.log(arr) // [2, 5, 45, 3, 2, 1]
复制代码
二十一、join()
将数组以括号中的值分割成字符串(不会改变原数组)
let arr=[1,2,3,45,5,2];
console.log(arr.join("_”)); // "1_2_3_45_5_2"
console.log(arr); // [1, 2, 3, 45, 5, 2]
复制代码
二十二、sort()
排序,将数组中的值进行排序,从大到小或从小到大(会改变原本的数组)
sort
原本的排序功能只能识别到个位数做比较,所以扩展使用以下方法:(排序方法有很多,这是最传统,也是使用频率较多的,其他的方法不再赘述)
let arr=[1,2,3,45,5,2];
array=arr.slice();
arr.sort(function(a,b){
return a-b
})
// [1, 2, 2, 3, 5, 45]
查看此时的arr数组:
console.log(arr) // [1, 2, 2, 3, 5, 45]
arr.sort(function(a,b){
return b-a
})
// [45, 5, 3, 2, 2, 1]
查看此时的arr数组:
console.log(arr) // [45, 5, 3, 2, 2, 1]
复制代码
当然我们有时是不可以改变原数组的,那么可以试试下面的方法将需要的内容拷贝出来即可:
let arr=[1,3,6,8,45,34,90,122,9,0];
let array=arr.slice();
array.push(34)
console.log(arr,array)
// [1,3,6,8,45,34,90,122,9,0],[1,3,6,8,45,34,90,122,9,0,34]
复制代码
二十三、 Array.protype.slice.call(arr,n,m) 截取数组,返回新数组(不会改变原数组)
参数(前包,后不含):
arr
:截取的数组 n
:截取开始位置 m
:截取结束位置
今天有学到一个新的方法,推荐给大家,数组中的
slice.call()
方法,返回一个截取的新数组,(前不包,后包含)接下来我们带入一个🌰来现身说法:
1.向后截取,第二个参数2是指给定截取的位置,删除当前位置前的元素,返回包含第二个参数之后的数组副本。
let arr = [1,2,5,3,6];
console.log(Array.prototype.slice.call(arr,2)) // [5,3,6]
2.向前截取,首先找到截取位置为2,然后找到截取截止位置4,返回从首位数第二个参数开始,截止到第四个位置的数组副本:
let arr = [1,2,5,3,6];
console.log(Array.prototype.slice.call(arr,2,4)) // [5,3]
复制代码
数组中的迭代方法filter()
, every()
,forEach()
,map()
,some()
,reduce
filter()
:对数组中的每一项运行给定函数,返回该函数会返回true
的项组成的数组。
every()
:对数组中的每一项运行给定函数,如果该函数对每一项都返回true
,则返回true
。
forEach()
:对数组中的每一项运行给定函数。这个方法没有返回值。
map()
:对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
some()
:对数组中的每一项运行给定函数,如果该函数对任一项返回true
,则返回true.
一、数组迭代方法之filter()
filter
返回的是一个符合某种条件的数组,并返回一个新数组,不会更改原数组,还可以过滤假值。
array.filter(function(item,index,array){
})
复制代码
filter
的回调函数接收三个参数,分别是当前索引元素,索引,原数组
item
:当前索引元素index
:索引array
:原数组
let arr=[1,3,6,8,45,34,90,122,9,0];
let array = arr.filter(function(element){
return element>10
})
console.log(array)
//筛选数组中大于10的值, [45, 34, 90, 122]
//查看原数组,并没有改变
console.log(arr) // [1,3,6,8,45,34,90,122,9,0]
复制代码
遍历数组的时候将返回值为
true
的元素放入新数组,我们可以利用这个函数删除一些不需要的元素,过滤假值。
const compact = arr=> arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]) // [1, 2, 3, "a", "s", 34]
复制代码
关于这个过滤假植,在很多工具库都有自己的方法进行处理,下面我们就某库中的方法和filter
做一个比较,看具体执行效率(认真脸)。
// 方法本身
function lodashCompact(array) {
var index = -1,
length = array == null ? 0 : array.length,
resIndex = 0,
result = [];
console.time("lodashCompact");
while (++index < length) {
var value = array[index];
if (value) {
result[resIndex++] = value
}
}
console.timeEnd("lodashCompact");
return result;
}
// lodash 方法实现
function test() {
lodashCompact(arr);
}
// filter 方法实现
function test2() {
console.time("filter用时共计")
const compacts = arr => arr.filter(Boolean)
console.timeEnd("filter用时共计")
}
复制代码
上面计算的是纯执行时间,filter
远远超越约7.6倍,推荐使用filter
!
二、数组迭代方法之every()
(主要是用于判断一个数组中的值是否符合某个标准。必须是每个值都符合才会返回true
。否则返回false
)
let arr = [1,2,3,4,5,4,3,2,1];
let everyResult = arr.every(function(item, index, array){
return (item > 2);
});
//判断数组中所有的值是否都大于2,如果都大于2,返回true,反之返回false.
console.log(everyResult) //false
复制代码
三、数组迭代方法之forEach()
(数组的循环遍历,对数组中的每一项运行给定函数。这个方法没有返回值。)
let arr=[1,3,6,8,45,34,90,122,9,0];
arr.forEach(function(item,index,array){
console.log(item,index,array)
})
/*
0 1 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
1 3 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
2 6 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
3 8 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
4 45 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
5 34 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
6 90 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
7 122 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
8 9 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
9 0 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
*/
复制代码
四、数组迭代方法之map()
数组的循环遍历,对数组中的每一项运行给定函数,返回每次函数调用的结果组成新的数组。
遍历数组,返回新的数组
array.map(function(item,index,array){
})
复制代码
map
的回调函数接收三个参数,分别是当前索引元素,索引,原数组
item
:当前索引元素index
:索引array
:原数组
[1, 2, 3].map(v => v + 1) // -> [2, 3, 4]
复制代码
let arr=[1,3,6,8,45,34,90,122,9,0];
arr.map(function(item,index,array){
console.log(index,item,array)
})
/*
0 1 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
1 3 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
2 6 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
3 8 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
4 45 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
5 34 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
6 90 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
7 122 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
8 9 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
9 0 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
*/
复制代码
五、数组迭代方法之some()
(对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true)
let numbers = [1,2,3,4,5,4,3,2,1];
let someResult = numbers.some(function(item, index, array){
return (item > 2);
});
//只要有一个返回true,则返回true
console.log(someResult); // true
复制代码
六、reduce 归并:迭代数组中的所有值,返回一个按条件计算的最终值。
reduce:
方法对数组中的每个元素执行一个由您提供的
reducer
函数(升序执行),将其结果汇总为单个返回值。用于执行减少、汇总、求和、求平均数
reducer 函数接收4个参数:
Accumulator (acc) (累计器)
Current Value (cur) (当前值)
Current Index (idx) (当前索引) 索引默认从1开始 可选
Source Array (src) (源数组) 可选
Array.reduce((Accumulator,Value,Index,Array)=>{
//dosomething
}
复制代码
let values = [1,2,3,4,5];
let sum = reduce(function(prev, cur, index, array){
return prev + cur;
}); // 15
//第一次执行回调函数,prev 是1,cur 是2。第二次,prev 是3(1 加2 的结果),cur 是3(数组的第三项)。这个过程会持续到把数组中的每一项都访问一遍,最后返回结果。
//通过循环遍历,返回数组中所有值的总和 15
复制代码
求和
let arr = [1,2,4,6,34,66];
let res = arr.reduce((tap,item,index)=>{
console.log(`第${index}次:${tap}+${item}`);
return tap+item
})
// 第1次:1+2
// 第2次:3+4
// 第3次:7+6
// 第4次:13+34
// 第5次:47+66
console.log(res) // 113
复制代码
求平均数
let arr = [1,2,4,6,34,66];
let res = arr.reduce((tap,item,index)=>{
if(index!==arr.length-1){
return tap+item
}else{
return tap/(arr.length)
}
});
console.log(res) // 7.833333333333333
复制代码
reduceRight:
let values = [1,2,3,4,5];
let sum = reduceRight(function(prev, cur, index, array){
return prev + cur;
});
//第一次执行回调函数,prev 是5,cur 是4。第二次,prev 是9(5加4 的结果),cur 是3(数组的第三项)。这个过程会持续到把数组中的每一项都访问一遍,最后返回结果。
//通过循环遍历,返回数组中所有值的总和 15
复制代码
ES6 中的 find
:找到数组中第一个符合条件到值。
1.当在数组中匹配到符合条件的元素,则返回符合条件的元素,之后的值不会再调用执行函数;
2.如果没有符合条件的元素返回 undefined;
注意: find() 对于空数组,函数是不会执行的。
注意: find() 并没有改变数组的原始值。
var arr = [1,2,3,4,5,6,7];
var ar = arr.find((elem)=>{
return elem>5
}) // 6
--------------------------------------
var arr = [1,2,3,4,5,6,7];
var ar = arr.find((elem)=>{
return elem>10
}) // undefined
复制代码
ES6 中的 Array.from: 方法用于将两类对象转为真正的数组
Array.from 方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
复制代码
如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组。
Array.from([1, 2, 3]); // [1, 2, 3]
复制代码
Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
//
Array.from([1, 2, 3], (x) => x * x); // [1, 4, 9]
复制代码
下面的例子将数组中布尔值为false的成员转为0。
Array.from([1, , 2, , 3], (n) => n || 0) // [1, 0, 2, 0, 3]
复制代码
另一个例子是返回各种数据的类型。
function typesOf () {
return Array.from(arguments, value => typeof value);
}
typesOf(null, [], NaN); // ['object', 'object', 'number']
复制代码
ES6中的 Array.prototype.flat() 用于将嵌套的数组“拉平”,变成一维的数组。
该方法返回一个新数组,对原数据没有影响。
[1, 2, [3, 4]].flat(); // [1, 2, 3, 4]
// 上面代码中,原数组的成员里面有一个数组,flat()方法将子数组的成员取出来,添加在原来的位置。
复制代码
flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。
[1, 2, [3, [4, 5]]].flat(); // [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2); // [1, 2, 3, 4, 5]
复制代码
上面代码中,flat()的参数为2,表示要“拉平”两层的嵌套数组。如果不知道有多少层嵌套,都需要转成一维数组,可以用Infinity关键字作为参数。
[1, [2, [3]]].flat(Infinity); // [1, 2, 3]
复制代码
如果原数组有空位,flat()方法会跳过空位。
[1, 2, , 4, 5].flat(); // [1, 2, 4, 5]
复制代码
ES6中的空值
ES5 对空位的处理,已经很不一致了,大多数情况下会忽略空位。
forEach()
, filter()
, reduce()
, every()
和some()
都会跳过空位。
map()
会跳过空位,但会保留这个值
join()
和toString()
会将空位视为undefined
,而undefined
和null
会被处理成空字符串。
// forEach方法
[,'a'].forEach((x,i) => console.log(i)); // 1
// filter方法
['a',,'b'].filter(x => true) // ['a','b']
// every方法
[,'a'].every(x => x==='a') // true
// reduce方法
[1,,2].reduce((x,y) => x+y) // 3
// some方法
[,'a'].some(x => x !== 'a') // false
// map方法
[,'a'].map(x => 1) // [,1]
// join方法
[,'a',undefined,null].join('#') // "#a##"
// toString方法
[,'a',undefined,null].toString() // ",a,,"
复制代码
ES6 则是明确将空位转为undefined。
作者:玖月晴空
链接:https://juejin.im/post/6844903555682271245
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。