JavaScript 数组常用方法

217 阅读10分钟

前情提要

数组常用方法,es6中新增的方法,是否会改变原数组,splice 和 slice 的区别

JavaScript 数组常用方法

改变原数组

  • shift —— 将第一个元素删除,并返回删除的元素,空即为 undefined
  • unshift —— 向数组开头添加元素,并返回新的长度
  • pop —— 删除最后一个元素,并返回删除的元素
  • push —— 向数组末尾添加元素,并返回新的长度
  • reverse —— 反转(颠倒)数组顺序
  • sort —— 对数组排序
  • splice(start, length, item) —— 删除、增加、替换数组元素,返回被删除的数组,无删除则不返回

不改变原数组

  • sconcat ——连接多个数组,并返回新的数组
  • join —— 将数组中所有元素以参数作为分隔符放入一个字符
  • slice(start, end) —— 返回选定元素组成的新数组(从 start 到 end 之间,不包括end)
  • map、filter、some、every

join,push,pop,shift,unshift,splice(i, n),concat,split,sort,reverse,slice(start, end)

ES5

forEach,map,filter,every,some, reduce,reduceRight, indexOf,lastIndexOf

ES6

from,of, copyWithin, find,findIndex,fill,includes,keys,values,entries

join

join(separator) —— 将数组的元素组起一个字符串,以separator为分隔符,默认用逗号为分隔符

var arr = [1,2,3];
console.log(arr.join()); // 1,2,3
console.log(arr.join("-")); // 1-2-3
console.log(arr); // [1, 2, 3](原数组不变)

// 通过join()方法可以实现重复字符串,只需传入字符串以及重复的次数,就能返回重复后的字符串
function repeatString(str, n) {
	return new Array(n + 1).join(str);
}
console.log(repeatString("abc", 3)); // abcabcabc
console.log(repeatString("hello", 5)); // hellohellohellohellohello

push

push() —— 从后面添加元素,并返回添加后数组的长度

let arr = [1,2,3,4,5]
console.log(arr.push(5))   // 6
console.log(arr) // [1,2,3,4,5,5]

pop

pop() —— 从后面删除 **一个 ** 元素,并返回删除的元素

let arr1 = [1,2,3,4,5]
console.log(arr1.pop())     // 5
console.log(arr1)  //[1,2,3,4]

shift

shift() —— 从前面删除 一个 元素,并返回删除的元素

let arr = [1,2,3,4,5]
console.log(arr.shift())  // 1
console.log(arr)   // [2,3,4,5]

unshift

unshift() —— 从前面添加元素,并返回添加后数组的长度

let arr = [1,2,3,4,5]
console.log(arr.unshift(2))    // 6
console.log(arr)  //[2,1,2,3,4,5]

splice(i, n) —— 删除、插入、替换

splice(i, n) —— 删除 从 i 开始之后的那个元素 ,并返回删除的元素组成的数组

  • i 索引值
  • n 个数(删除元素的长度)
// 删除
var arr = [1,3,5,7,9,11];
var arrRemoved = arr.splice(0,2);
console.log(arr); //[5, 7, 9, 11]
console.log(arrRemoved); //[1, 3]
// 插入 —— 第二个参数为 0
var arrRemoved2 = arr.splice(2,0,4,6);
console.log(arr); // [5, 7, 4, 6, 9, 11]
console.log(arrRemoved2); // []
// 替换
var arrRemoved3 = arr.splice(1,1,2,4);
console.log(arr); // [5, 2, 4, 4, 6, 9, 11]
console.log(arrRemoved3); //[7]

concat (原数组未被修改)

concat[arr] —— 连接两个数组,将参数添加到原数组创建的副本中,并返回新构建的数组

// 传入的不是数组,则直接把参数添加到数组后面,如果传入的是数组,则将数组中的各个项添加到数组中
var arr = [1,3,5,7];
var arrCopy = arr.concat(9,[11,13]);
console.log(arrCopy); //[1, 3, 5, 7, 9, 11, 13]
console.log(arr); // [1, 3, 5, 7](原数组未被修改)
// concat方法只能将传入数组中的每一项添加到数组中
// 如果传入数组中有些项是数组,那么也会把这一数组项当作一项添加到arrCopy2中
var arrCopy2 = arr.concat([9,[11,13]]);
console.log(arrCopy2); //[1, 3, 5, 7, 9, Array[2]]
console.log(arrCopy2[5]); //[11, 13]

split

split(string) —— 将字符串转化为数组

let str = '123456'
console.log(str.split('')) // ["1", "2", "3", "4", "5", "6"]

sort

sort(arr) —— 将数组进行排序,并返回排序后的数组;默认按照最左边的数字进行排序,不是按照数字大小排序

  • 在排序时,sort()方法会调用每个数组项的 **toString()**转型方法,然后比较得到的字符串
// 默认按照最左边的数字(从小到大)进行排序
let arr = [2,10,6,1,4,22,3]
console.log(arr.sort())   // [1, 10, 2, 22, 3, 4, 6]
// 从小到大排序
let arr1 = arr.sort((a, b) =>a - b)  
console.log(arr1)   // [1, 2, 3, 4, 6, 10, 22]
// sort接收比较函数作为参数
function compare(value1, value2) {
    if (value1 < value2) {
    	return -1;
    } else if (value1 > value2) {
    	return 1;
    } else {
    	return 0;
    }
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]
// 从大到小排序
let arr2 = arr.sort((a, b) =>b-a)  
console.log(arr2)  // [22, 10, 6, 4, 3, 2, 1]
// sort接收比较函数作为参数function compare(value1, value2) {
function compare(value1, value2) {
    if (value1 < value2) {
    	return 1;
    } else if (value1 > value2) {
    	return -1;
    } else {
    	return 0;
    }
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]

reverse —— 原数组改变

reverse(arr) —— 将数组反转,并返回反转后的数组

var arr = [13, 24, 51, 3];
console.log(arr.reverse()); //[3, 51, 24, 13]
console.log(arr); //[3, 51, 24, 13](原数组改变)

slice(start, end) —— 原数组未改变

slice(start, end) —— 截取 start 到 end之间的元素 (不包含end项)组成的新数组,并返回新数组

var arr = [1,3,5,7,9,11];
var arrCopy = arr.slice(1);
var arrCopy2 = arr.slice(1,4);
var arrCopy3 = arr.slice(1,-2);
var arrCopy4 = arr.slice(-4,-1);
console.log(arr); //[1, 3, 5, 7, 9, 11](原数组没变)
console.log(arrCopy); //[3, 5, 7, 9, 11]
console.log(arrCopy2); //[3, 5, 7]
console.log(arrCopy3); //[3, 5, 7]
console.log(arrCopy4); //[5, 7, 9]

ES5

forEach,map,filter,every,some, reduce,reduceRight, indexOf,lastIndexOf

forEach

forEach() —— 对数组进行循环遍历

var arr = [1, 2, 3, 4, 5];
arr.forEach(function(x, index, a){
console.log(x + '|' + index + '|' + (a === arr));
});
// 输出为:
// 1|0|true
// 2|1|true
// 3|2|true
// 4|3|true
// 5|4|true

map

map((item) => {return item * item}) —— 映射,每次函数调用的结果组成的数组

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(item){
return item*item;
});
console.log(arr2); //[1, 4, 9, 16, 25]

filter

filter((v, i) => {return v >= 8}) —— 过滤,返回满足过滤条件组成的数组

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
return index % 3 === 0 || x >= 8;
}); 
console.log(arr2); //[1, 4, 7, 8, 9, 10]

every

every() —— 数组中所有项都满足条件,才会返回 true

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
return x < 10;
}); 
console.log(arr2); //true
var arr3 = arr.every(function(x) {
return x < 3;
}); 
console.log(arr3); // false

some

some() —— 只要有一项满足条件,就会返回 true

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
return x < 3;
}); 
console.log(arr2); //true
var arr3 = arr.some(function(x) {
return x < 1;
}); 
console.log(arr3); // false

reduce

reduce() 和 reduceRight() —— 实现迭代数组中所有项,然后构建一个最终返回的值

reduce() —— 从数组的第一项开始,逐个遍历到最后

参数: reduce(callback, initialValue)

  • previousValue 必选 --上一次调用回调返回的值,或者是提供的初始值(initialValue

  • currentValue 必选 --数组中当前被处理的数组项

  • index 可选 --当前数组项在数组中的索引值

  • array 可选 --原数组

  • initialValue: 可选 --初始值

  • 实行方法:回调函数第一次执行时,preValuecurValue 可以是一个值,如果 initialValue 在调用 reduce() 时被提供,那么第一个 preValue 等于 initialValue ,并且 curValue 等于数组中的第一个值;如果 initialValue 未被提供,那么 preValue 等于数组中的第一个值.

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
	return prev + cur;
},10);
console.log(sum); //25

reduce 高级用法

// 计算数组中每个元素出现的次数
let names = ['peter', 'tom', 'mary', 'bob', 'tom','peter'];

let nameNum = names.reduce((pre,cur)=>{
  if(cur in pre){
    pre[cur]++
  }else{
    pre[cur] = 1
  }
  return pre
},{})
console.log(nameNum); //{ peter: 2, tom: 2, mary: 1, bob: 1 }
// 数组去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
      return pre.concat(cur)
    }else{
      return pre
    }
},[])
console.log(newArr);// [1, 2, 3, 4]

reduceRight

reduceRight() —— 从数组的最后一项开始,向前遍历到第一项

var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
},10);
console.log(sum); //25

indexOf

indexOf() —— 接收两个参数:要查找的项 和 查找起点位置的索引(可选) ;从头(0)开始向后查找;并返回第一个找到的索引值,若不存在返回 -1

var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.indexOf(5,2)); //2
console.log(arr.indexOf("5")); //-1

lastIndexOf

lastIndexOf() —— 接收两个参数:要查找的项 和 查找起点位置的索引(可选) ;从数组末尾开始向前查找;并返回第一个找到的索引值,若不存在返回 -1

var arr = [1,3,5,7,7,5,3,1];
console.log(arr.lastIndexOf(5)); //5
console.log(arr.lastIndexOf(5,4)); //2

ES6

from,of, copyWithin, find,findIndex,fill,includes,keys,values,entries

from

from() —— 将伪数组变成数组,只要有length的就可转成数组

let str = '12345'
console.log(Array.from(str))    // ["1", "2", "3", "4", "5"]
let obj = {0:'a',1:'b',length:2}
console.log(Array.from(obj))   // ["a", "b"]

of

of() —— 将一组值转换成数组,类似于声明数组

let str = '11'
console.log(Array.of(str))   // ['11']
// 等价于
console.log(new Array('11'))  // ['11]
// 但是new Array()有缺点,就是参数问题引起的重载
console.log(new Array(2))   //[empty × 2]  是个空数组
console.log(Array.of(2))    // [2]

copyWithin

copyWithin() —— 在当前数组内部,将制定位置的数组复制到其他位置,会覆盖原数组项,返回当前数组

参数:

  • target --必选 索引从该位置开始替换数组项

  • start --可选 索引从该位置开始读取数组项,默认为0.如果为负值,则从右往左读。

  • end --可选 索引到该位置停止读取的数组项,默认是 Array.length ,如果是负值,表示倒数

let arr = [1,2,3,4,5,6,7]
let arr1 = arr.copyWithin(1)
console.log(arr1)   // [1, 1, 2, 3, 4, 5, 6]
let arr2 = arr.copyWithin(1,2)
console.log(arr2)   // [1, 3, 4, 5, 6, 7, 7]
let arr3 = arr.copyWithin(1,2,4)
console.log(arr3)   // [1, 3, 4, 4, 5, 6, 7]

find

find() —— 找到第一个符合条件的数组成员

let arr = [1,2,3,4,5,2,4]
let arr1 = arr.find((value, index, array) =>value > 2)
console.log(arr1)   // 3

findIndex

findIndex() —— 找到第一个符合条件的数组成员的索引值

let arr = [1,2,3,4,5]
let arr1 = arr.findIndex((value, index, array) => value > 3)
console.log(arr1)  // 3

fill ——(改变原数组)

fill() —— 使用给定的值,填充一个数组, ps: 填充完后会改变原数组

  • target -- 待填充的元素

  • start -- 开始填充的位置-索引

  • end -- 终止填充的位置-索引(不包括该位置)

let arr = [1,2,3,4,5]
let arr1 = arr.fill(5)
console.log(arr1)  // [5, 5, 5, 5, 5]
console.log(arr)   // [5, 5, 5, 5, 5]
let arr2 = arr.fill(5,2)
console.log(arr2)
let arr3 = arr.fill(5,1,3)
console.log(arr3)

includes

includes() —— 判断数中是否包含给定的值

let arr = [1,2,3,4,5]
let arr1 = arr.includes(2)  
console.log(arr1)   // ture
let arr2 = arr.includes(9) 
console.log(arr2)    // false
let arr3 = [1,2,3,NaN].includes(NaN)
console.log(arr3)  // true
// ps:
// includes 与 indexOf() 的区别:
// 1 indexOf() 返回的是数值,而 includes() 返回的是布尔值
// 2 indexOf() 不能判断 NaN,返回为 -1 ,includes() 则可以判断

keys

keys() —— 遍历数组的键名

let arr = [1,2,3,4]
let arr2 = arr.keys()
for (let key of arr2) {
    console.log(key);   // 0,1,2,3
}

values

values() —— 遍历数组键值

let arr = [1,2,3,4]
let arr1 = arr.values()
for (let val of arr1) {
     console.log(val);   // 1,2,3,4
}

entries

entries() —— 遍历数组的键名和键值 ,

  • 返回迭代数组
  • 迭代数组中每个值 前一个是索引值作为 key, 数组后一个值作为 value
let arr = [1,2,3,4]
let arr1 = arr.entries()
for (let e of arr1) {
    console.log(e);   // [0,1] [1,2] [2,3] [3,4]
}

splice 和 slice 的区别

  • splice

    • 删除-用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数)
    • 插入-向数组指定位置插入任意项元素。三个参数,第一个参数(其实位置),第二个参数(0),第三个参数(插入的项)
    • 替换-向数组指定位置插入任意项元素,同时删除任意数量的项,三个参数。第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项)
  • slice

    • let arr = [ ‘a’, ‘b', ‘c', ‘d', ‘e' ]

    • arr.slice(1) —— 返回除第一个元素后的所有元素组成的新数组 => ["b", "c", "d", "e"]

    • arr.slice(-1) —— 返回最后一个元素组成的新数组 => ["e"]

    • arr.slice(2, 4) —— 返回中间一段元素(不包含4)组成的新数组 => ["c", "d"]

    • arr.slice(-3, -1) —— 两个参数均为负数,返回中间一段元素组成的新数组 => ["c", "d"]

针对 ES5 新增的方法浏览器支持情况:

  • Opera 11+
  • Firefox 3.6+
  • Safari 5+
  • Chrome 8+
  • Internet Explorer 9+