基本方法
-
添加/删除元素:
push(...items)—— 向尾端添加元素,pop()—— 从尾端提取一个元素,shift()—— 从首端提取一个元素,unshift(...items)—— 向首端添加元素,splice(pos, deleteCount, ...items)—— 从pos开始删除deleteCount个元素,并插入items。slice(start, end)—— 创建一个新数组,将从索引start到索引end(但不包括end)的元素复制进去。concat(...items)—— 返回一个新数组:复制当前数组的所有元素,并向其中添加items。如果items中的任意一项是一个数组,那么就取其元素。
-
搜索元素:
indexOf/lastIndexOf(item, pos)—— 从索引pos开始搜索item,搜索到则返回该项的索引,否则返回-1。includes(value)—— 如果数组有value,则返回true,否则返回false。find/filter(func)—— 通过func过滤元素,返回使func返回true的第一个值/所有值。findIndex和find类似,但返回索引而不是值。
-
遍历元素:
forEach(func)—— 对每个元素都调用func,不返回任何内容。
-
转换数组:
map(func)—— 根据对每个元素调用func的结果创建一个新数组。sort(func)—— 对数组进行原位(in-place)排序,然后返回它。reverse()—— 原位(in-place)反转数组,然后返回它。split/join—— 将字符串转换为数组并返回。reduce/reduceRight(func, initial)—— 通过对每个元素调用func计算数组上的单个值,并在调用之间传递中间结果。
-
其他:
-
Array.isArray(arr)检查arr是否是一个数组。 -
some\every检查数组。 -
flat\flatMap从多维数组创建一个新的扁平数组。
-
-
不改变自身的方法
concat、join、slice、toString、toLocaleString、indexOf、lastIndexOf、includes -
不会改变自身的数组遍历方法
forEach、every、some、filter、map、reduce、reduceRight、entries、find、findIndex、keys、values
总结:
- 所有插入元素的方法,比如
push、unshift一律返回数组新的长度; - 所有删除元素的方法,比如
pop、shift、splice一律返回删除的元素,或者返回删除的多个元素组成的数组; - 部分遍历方法,比如
forEach、every、some、filter、map、find、findIndex,它们都包含function(value,index,array){}和thisArg这样两个形参。
数组扁平化
数组自带方法Array.prototype.flat()
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
var newArray = arr.flat([depth])
当
depth大于数组自身深度时,则会自动展开为一维数组,所以使用
Infinity,可展开任意深度的嵌套数组
-
案例
const arr1 = [0, 1, 2, [3, 4]]; console.log(arr1.flat()); //[1,2,3,4] const arr2 = [0, 1, 2, [[[3, 4]]]]; console.log(arr2.flat(4));//[1,2,3,4]
手写替代方案
reduce+contact
arr.reduce((acc, val) => acc.concat(val), []);
const arr1 = [0, 1, 2, [3, 4]];
const arr2 = [0, 1, 2, [[[3, 4]]]];
let arr4 = arr1.reduce((acc, val) => acc.concat(val), []);//[ 0, 1, 2, 3, 4 ]
let arr5 = arr2.reduce((acc, val) => acc.concat(val), []);//[ 0, 1, 2, [ [ 3, 4 ] ] ]
从上面可以看到直接使用的话,只能实现二级数组扁平化,当数组嵌套层数过多,就无法得到想要的结果
reduce+contact+递归
const arr2 = [0, 1, 2, [[[3, 4]]]];
//写法一
function flatDeep(arr, d = 1) {
return d > 0
? arr.reduce((acc, val) => {
if (Array.isArray(val)) {
return acc.concat(flatDeep(val,d - 1));
} else {
return acc.concat(val);
}
}, [])
: arr.slice();
}
//写法二
function flatDeep(arr, d = 1) {
return d > 0
? arr.reduce(
(acc, val) =>
acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val),
[]
)
: arr.slice();
}
console.log(flatDeep(arr2, Infinity));//[ 0, 1, 2, 3, 4 ]
forEach+push+递归
function flatDeep2(arr = [], d = 1) {
let result = [];
(function flat(arr, d) {
arr.forEach((item) => {
if (Array.isArray(item) && d > 0) {
flat(item, d - 1);
} else {
result.push(item);
}
});
})(arr, d);
return result;
}
console.log(flatDeep2(arr2, Infinity));//[ 0, 1, 2, 3, 4 ]
Generator函数实现
常规函数只会返回一个单一值(或者不返回任何值)。
而
Generator可以按需一个接一个地返回(yield)多个值。它们可与 iterable 完美配合使用,从而可以轻松地创建数据流。一个 generator 的主要方法就是
next()。当next()被调用时,它会恢复上图所示的运行,执行直到最近的yield 语句。然后函数执行暂停,并将产出的(yielded)值返回到外部代码。
const arr2 = [0, 1, 2, [[[3, 4]]]];
function* flatGenerator(arr) {
for (var value of arr) {
if (Array.isArray(value)) {
yield* flatGenerator(value);
// yield* 这个特殊的语法来将一个 generator “嵌入”(组合)到另一个 generator
} else {
yield value;
}
}
}
let newarr = [...flatGenerator(arr2)];
console.log(newarr);//[ 0, 1, 2, 3, 4 ]