最新常用Array数组操作

@一棵菜菜  May 21, 2019

前言

写久了业务代码的我,已经要被社会抛弃了。今天回过头去巩固基础知识,发现有很多自己业务中不经常用,或者说是不知道那个方法,导致自己重写一个方法去实现。关于 Array 对象的方法你是否只用concat、join、pop、push、shift、unshift、reverse、sort、slice、splice、toString、indexOf、find等?接下来我们就一起回顾一下那些我们用的少或者没有用过的 Array 对象方法!【深有同感。。。】

有些都是 ES6的哈!要注意兼容性。

1. Array.from(object, mapFunction, thisValue)【ES6】

从一个类似数组或可迭代对象中创建一个新的数组实例

/**
 * @description - 从一个类似数组或可迭代对象中创建一个新的数组实例(伪数组对象:拥有一个 length 属性和若干索引属性的任意对象;可迭代对象:可以获取对象中的元素,如 Map和 Set 等)
 * @param arrayLike - 想要转换成数组的伪数组对象或可迭代对象.
 * @param mapFn - 可选参数,如果指定了该参数,新数组中的每个元素会执行该回调函数.
 * @param thisArg - 可选参数,执行回调函数 mapFn 时 this 对象.
 * @return { Array } - 一个新的数组实例
 */
Array.from(arrayLike[, mapFn[, thisArg]])

常用示例

// Array from a String
Array.from('foo');// ["f", "o", "o"],类似:'foo'.split('')

Array.from([1,2,3]); // [1,2,3]

// Array from an Array-like object (arguments)
function f() {
  return Array.from(arguments);
}
f(1, 2, 3);
// [1, 2, 3]

// 类数组(把带有lenght属性的类似数组的对象转换为数组)
Array.from({length: 5});
// [undefined, undefined, undefined, undefined, undefined]
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]

// 注意:
Array.from({'0':'w','1':'b'}) // []
// 返回数组的长度取决于对象中的length,故此项必须有!
Array.from({'0':'w','1':'b',length:2})// ["w", "b"]

示例

// Array from a Set
let s = new Set(['foo', window]);
Array.from(s)
// ["foo", window]

// Array from a Map
let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m);
// [[1, 2], [2, 4], [4, 8]]

// 在Array.from中使用箭头函数
Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]

// 改变回调函数 mapFn 时 this 对象
Array.from({[1, 2, 3], function(){console.log(this)});
// 浏览器环境下是三次 Window对象

var obj ={name: 'obj'}
Array.from({[1, 2, 3], function(){console.log(this)}, obj);
// 三次 obj 对象

2. Array.prototype.includes()【ES6】

用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。

注意:对象数组不能使用 includes 方法来检测。

语法
/**
 * @description - 用来判断一个数组是否包含一个指定的值。
 * @param valueToFind - 需要查找的元素值。
 * @param fromIndex - 可选的。从fromIndex 索引处开始查找 valueToFind。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜 (即使从末尾开始往前跳 fromIndex 的绝对值个索引,然后往后搜寻)。默认为 0。
 * @return { Boolean } - 是否包含。
 */
arr.includes(valueToFind[, fromIndex])

示例

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

3. Array.prototype.fill(value, start, end)【ES6】

数组填充。fill() 方法用一个固定值填充一个数组中 从起始索引到终止索引内的全部元素。不包括终止索引。会改变原数组

 let arr=['w','b'];
 arr.fill('i')// ['i','i'],
 arr.fill('o',1)// ['i','o'],第二个参数表示填充起始位置

new Array(4).fill('k').fill('r',1,3)//结果:['k','r','r','k'],从索引为1的位置开始填充,直到索引为2的位置(不包含索引为3的位置)

new Array(3).fill(null);// [null, null, null]

4. 如何把类数组(如函数参数arguments)转成数组?

方法1: Array.from()

具体讲解见本文的「1」。

function toArray() {
  return Array.from(arguments);
}

方法2: Array.prototype.slice.call()

说明:slice()方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。

注意:不是splice (splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目)

function toArray() {
  return Array.prototype.slice.call(arguments);
}

var list1 = toArray(1, 2, 3); // [1, 2, 3]

方法3: rest 参数(剩余运算符) 【ES6】

阅读阮一峰:rest 参数
更多查看我的文章《ES6的展开运算符和rest运算符(…)》

优点:ES6 引入 rest 参数(即剩余运算符,形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了
rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

// bad arguments变量的写法
function sortNumbers1() {
  const args = Array.prototype.slice.call(arguments);
  return args.sort();
}

// good rest参数的写法【推荐】
const sortNumbers2 = (...args) => args.sort();

var a = sortNumbers1(3,2,1); // [1,2,3]
var b = sortNumbers2(3,2,1); // [1,2,3]
上面代码的两种写法,比较后可以发现,rest 参数的写法更自然也更简洁。
arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.prototype.slice.call先将其转为数组。rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。
所以建议不要在函数体内使用 arguments 变量,而是使用 rest 参数(...)代替。

例子:

const sortNumbers = (array, ...rest) => array.concat(rest);

var a = [10];
var b = sortNumbers(a,3,2,1); // [10,3,2,1]

我的小结

ES6常用的:

  • 创建array:Array.from(object, mapFunction, thisValue),
  • 是否包含:.includes(val)
  • 填充:.fill(value, start, end):不包含endIndex项。fill 会改变原数组。
  • .find(function(val, key, arr),thisValue): 返回通过测试(函数内判断)的数组的第一个元素的值。 find() 对于空数组不会执行函数,不会改变原数组。
  • .findIndex(function(val, key, arr), thisValue):返回传入一个测试条件(函数)符合条件的数组第一个元素位置
var data = Array.from({length:3},(val,index)=>index);// data = [0,1,2] 

[1,2,3].includes(3);// true

var test = [1,2,3];
test.fill(0,0,2); // test =[0,0,3]

[1,2,3,4].find((val,key)=>{return val>2}) // 3
[{age:1},{age:2},{age:5}].find((val)=>{return val.age>2}) // {age: 5} 

[1,2,3,4].findIndex((val,key)=>{return val>2}) // 2

ES5 常用的:

更多查看我的文章《Array类型介绍+常用数组操作》
[1,2,3].some((val, key, array) => {
  return val > 2;
}); // true
[1,2,3].every((val, key, array) => {
  return val > 2;
});// false
var totalValue = [1,2,3].reduce((total,current,index,array)=>{
return total+current
},0);// totalValue = 6

其他操作:

// 把类数组(如函数参数arguments)转成数组
function tt(){
return Array.from(arguments);
// 或
// return Array.prototype.slice.call(arguments);
}
tt(1,2,3); // [1,2,3]

// rest运算符可提供一个真正的数组
function tt2(...args){
  return args;
}
tt2(1,2,3); // [1,2,3]

本文部分摘抄自此文:《9102年了,Array数组的方法赶紧用起来!》
其他常用的见我的文章《Array类型介绍+常用数组操作》

添加新评论