javascript中数组的回顾

数组在javascript中使用度很是频繁,我总结了一些在数组中很常见的问题。javascript

关于数组中的方法很是多,我总结了一张表来大体了解数组中的方法java

Array中的方法 含义 改变原数组 返回值 ES6新增
concat 合并两个或多个数组 false 新数组 false
copyWithin 浅复制数组的一部分到同一数组中的另外一个位置 true 改变后的数组 true
entries 返回数组迭代器对象,该对象包含数组中每一个索引的键/值对 false 数组迭代器 true
every 测试数组的全部元素是否都经过了指定函数的测试 false 布尔值,true/false false
fill 用一个固定值填充一个数组中从起始索引到终止索引内的所有元素 true 改变后的数组 true
filter 建立一个新数组, 其包含经过所提供函数实现的测试的全部元素 false 新数组 false
find 返回数组中知足提供的测试函数的第一个元素的值。不然返回undefined false javascript语言类型 true
findIndex 返回数组中知足提供的测试函数的第一个元素的索引。不然返回-1 false 数组索引 true
forEach 遍历数组 false undefined false
includes 判断一个数组是否包含一个指定的值 false 布尔值,true/false true
indexOf 返回在数组中能够找到一个给定元素的第一个索引,若是不存在,则返回-1 false 数组索引 false
join 将数组(或一个类数组对象)的全部元素链接到一个字符串中 false 字符串 false
keys Array迭代器,它包含数组中每一个索引的键 false 数组迭代器 true
lastIndexOf 返回指定元素在数组中的最后一个的索引,若是不存在则返回 -1 false 数组索引 false
map 遍历数组 false 新数组 false
pop 从数组中删除最后一个元素,并返回该元素的值 true 数组元素 false
push 将一个或多个元素添加到数组的末尾,并返回新数组的长度 true 数组长度 false
reduce 对累加器和数组中的每一个元素(从左到右)应用一个函数,将其减小为单个值 false 函数返回值 false
reduceRight reduce执行方向相反,从右到左 false 函数返回值 false
reverse 将数组中元素的位置颠倒 true 改变后的数组 false
shift 从数组中删除第一个元素,并返回该元素的值 true 数组元素 false
slice 可从已有的数组中返回选定的元素 false 新数组 false
some 测试数组中的某些元素是否经过由提供的函数实现的测试 false 布尔值,true/false false
sort 在适当的位置对数组的元素进行排序 true 一个新数组 false
splice 删除现有元素和/或添加新元素来更改一个数组的内容 true 删除的元素数组 false
toLocaleString 返回一个字符串表示数组中的元素 false 字符串 false
toString 返回一个字符串,表示指定的数组及其元素 false 字符串 false
unshift 将一个或多个元素添加到数组的开头 true 数组长度 false
values 一个数组迭代器对象,该对象包含数组每一个索引的值 false 数组迭代器 true

从这个表中咱们要当心几个方法,reverse和sort会改变原数组,并返回改变的新数组,push和unshift方法返回的是数组长度而不是数组,forEach方法返回的是undefined不是数组。数组

此外,我还需提一下slice和splice这两个方法,说实话这两个方法看起来很像,容易让人搞混,最关键的是用到的频率还蛮高的,这两个方法就像字符串中substr和substring这两个老兄弟,闲着没事就喜欢去迷惑别人,本人就曾深深的被这两个方法伤害过。app

slice接受两个参数start和end,表明须要截取的数组的开始序号和结束序号。函数

var arr = [4,3,5,8,9,6];
arr.slice(0)    // [4,3,5,8,9,6],end能够省略,默认为数组长度
arr.slice(0,4)   //[4,3,5,8]
arr.slice(-1);   //[6],  start为负数表明从数组截取的开始序号从尾部算起
arr.slice(0,-1);  //[4,3,5,8,9]   end为负数表示结束序号从尾部算起
arr.slice(2,0);   //[]
arr.slice(-1,-1);   //[]  若是start和end符号相同,end必定大于start,不然返回的会是[]

splice的参数为index,deleteCount和...items,index表示须要删除或添加原数时的位置,负数表示从尾部算起,deleteCount表示要删除的元素,0表示不删除。其中items表示添加的元素个数。学习

var arr = [4,3,5,8,9,6];
arr.splice(0,0)      //返回[], arr=[4,3,5,8,9,6];
arr.splice(0,2)      //返回[4,3], arr=[5,8,9,6];
arr.splice(0,2,3,4)  //返回[5,8], arr=[3,4,9,6];

splice不论是添加仍是删除元素,返回的都是删除元素的列表,splice是先作删除操做,后添加测试

var arr = [4,3,5];
arr.splice(3,1,8,9);     //返回[], arr= [4, 3, 5, 8, 9];
//若是index大于数组长度,那么splice不会删除元素

注意:虽然slice和splice都返回一个新的数组,可是slice不会改变原数组,splice会改变原数组,这个区别很是关键。this

最后在加一些常常会问到的数组问题。code

1.建立数组

//数组字面量建立
var arr = [1,2];

//Array构造器建立;
var arr = Array(1,2);     //[1,2]  能够用new操做符,也能够不用
//Array构造器有个局限性,不能建立只有单个数字的数组
var arr = Array(10)       //建立的是一个长度为10的空数组,并非[10]
//若是传入的不是Number类型的数字,那么没有任何问题
var arr = Array('10')     //['10']

//此时若是要建立只有单个数字的数组,能够用Array.of方法
var arr = Array.of(10)    //[10]
var arr = Array.of(1,2)   //[1,2]

//Array.from( items [ , mapfn [ , thisArg ] ] )
//items是个可迭代对象,mapfn是遍历该迭代对象的function,thisArg是mapfn中的this对象
var arr = Array.from([1,2,3])    //[1,2,3]

Array.from是很是有用的建立数组方法,能把字符串转化为数组,Map,Set也能转成数组。对象

Array.from('abc')        //['a','b','c'];
Array.from(new Set([1,2,3]))  //[1,2,3],固然这个例子毫无心义
Array.from(new Map([[1,2],[3,4]]))  //[[1,2],[3,4]]

咱们知道用Array构造器建立的数组是个空数组,map,forEach方法并不能遍历这个数组。

var arr = Array(10);
arr.forEach((item,index) => console.log(index))   //不会有输出
//map,forEach循环判断的是该对象上有没有对应的属性
arr.hasOwnProperty(0)            //false,以hasOwnProperty为判断标准
//Array.from中的mapfn方法是以迭代方式来判断的,所以
Array.from(arr,(item,index)=>console.log(index))   //0,1,2,3,4,5,6,7,8,9

因为这个缘由,咱们能够快速对数组初始化,好比建立一个0到99的数组

Array.from(Array(100),(item,index)=>index);
//固然,若是你用到上表中Array的keys方法那更快捷
Array.from(Array(100).keys());

2.数组去重

方法一,建立对象的键值惟一性来进行去重:

var arr = [1,2,3,1,3,5,3,2];
var _arr = [];
var obj = {};
arr.forEach(item => {
    if(!obj[item]){
       _arr.push(item);
       obj[item] = true;
    }
})
arr = _arr;

方法二,结合Set的键值惟一性以及Array.from方法能够快速数组去重:

var arr = Array.from(new Set([1,2,3,1,3,5,3,2]))   //[1,2,3,5]

3.快速复制一个数组

var arr = [1,2,3,4];
var arr1 = arr.slice();
var arr2 = arr.concat();
注:这里的复制指的是浅拷贝

4.求数组最大值,最小值

这里的数组指的是全是数字的数组

方法一,sort排序后取值

var arr = [1,4,6,2,33,19,6,9];
var maxvalue = arr.sort((a,b) => b>a )[0]
var minvalue = arr.sort((a,b) => a>b )[0]

方法二,Math的max和min方法调用

var arr = [1,4,6,2,33,19,6,9];
var maxvalue = Math.max.apply(null,arr);   //33
var minvalue = Math.min.apply(null,arr);   //1

5.数组排序

在不用系统自带的sort的状况下对数组排序有不少方法,好比冒泡、插入以及快速排序等。但我总以为这些排序方法仍是过于复杂,有没有更快以及更方便的排序,我思考了很久,后来先想到了能够用数组的序号进行排序。原理是把数组1中的值变成数组2中的序号:

var arr = [3,4,6,2,8,7,5],
    arr2 = [];
arr.forEach(item => arr2[item] = item);
arr = [];
arr2.forEach(item => arr.push(item));

写完以后本身感受美滋滋,可以后发现若是数组中有负数,不就都玩完了吗。因而赶忙改:

var arr = [3,-4,6,-2,-8,7,5],
    parr = [];
    narr = [];
arr.forEach(item => item>=0?parr[item] = item:narr[-item] = item);
arr = [];
parr.forEach(item => arr.push(item));
narr.forEach(item => arr.unshift(item));
注:若是数组中有重复数字则排序方法有误,会把重复数字去掉。

写完以后发现其实也没有比冒泡、插入以及快速排序的方法快多少。

6.求一个整数数组是否包含另外一个整数数组

一开始我想到一个方法,把两个数组转换成字符串,在进行includes或者indexOf判断就能够了,后来我发现了问题:

var a = [2,4,8,6,12,67,9];
var b = [8,6,12];
a.join(',').includes(b.join(','));   //true;  这是能够的

var b = [8,6,1]
a.join(',').includes(b.join(','));   //true;  这竟然也能够,显然有问题

//因而改为
a.join(',').includes(','+b.join(',')+',');  //false;

//后来我又发现若是b数组在a数组的开头和结尾都会有问题,因而又改为以下:

(','+a.join(',')+',').includes(','+b.join(',')+',');  //false;

写这篇文章主要是对本身学习数组作一个总结。若是对上面的问题有更好的解答,欢迎留言告知。

相关文章
相关标签/搜索