ES数组遍历一直是前端开发中的重中之重,日常很少去总结这些东西,今天趁着休息日,好好的翻阅了一下MDN,然后结合一些demo
来做一个数组遍历的总结。不对之处,还请留言区告知~。
注意,大多数方法接收回调函数,回调函数的参数基本一致,均是 value/index/array三个
1、for
循环遍历,支持break
和continue
{
let arr = [1, 2, 3, 4]
for (let i = 0; i < arr.length; i++) {
const item = arr[i]
console.log(item
}
}
2、forEach
不可使用break
or continue
,如果想中止循环,可能需要抛出异常
{
let arr = [1, 2, 3, 4]
arr.forEach(value => {
console.log(value)
})
}
3、map
原型方法,该方法可以返回一个由回调函数返回值组成的一个新数组。
{
let arr = [1, 2, 3]
let result = arr.map((value, index, arr) => {
console.log(value, index, arr)
})
console.log(result)
// 网红面试题
let numbers = ["16", "20", "30"]
// 你可能期望返回 [1, 2, 3],但是结果却返回[1, NaN, NaN]
console.log(numbers.map(parseInt))
// 这是因为 默认parseInt第二个参数是代表进制,但是上面程序在执行的时候一次将 0,1,2作为进制传递进去了 ,
// 如果想要解决这个问题可以这样做
function myParseInt(item) {
return parseInt(item, 10)
}
console.log(numbers.map(myParseInt))
}
4、filter
原型方法,该方法返回一个由符合过滤条件的元素的集合。
{
let arr = [1, 3, 5, 8, 9]
let result = arr.filter(value => value >= 2)
console.log(result)
}
5、some
原型方法,该方法是用于测试数组中是否至少有一项是符合条件的。
{
let arr = [1, 2, 3, 4]
console.log(arr.some(value => value === 2))
}
6、every
原型方法,该方法是用于测试数组中所有元素均满足某条件的。
{
let arr = [0, 2, 4, 6, 8]
console.log(arr.every(value => value % 2 === 0))
}
7、ES6中的for...of
{
let arr = [1, 2, 3]
for (const item of arr) {
console.log(item)
}
}
8、面试必考之reduce
,这个函数可以说是相当强大,这里需要重点介绍
Array.prototype.reduce
/**
* 函数基本说明
*
* 该函数接收两个参数:
* 1、一个回调函数
* 这个回调函数包含4个参数:
* a. prev 上一次回调函数返回的值或者reduce的初始值
* b. current 当前遍历项
* c. index 当前遍历索引 如果没有提供reduce的第二个参数,那么这个索引将从1开始
* d. array 调用reduce的数组
* 2、初始值
*
*
* 返回值:
* 返回回调函数累计处理的结果
*
*
*/
上面先简单说明一下这个函数的基本用法,以及参数的含义,下面针对一些应用场景做一些示例
- 求和
const arr = [100, 23, 34, 102, 28, 47, 75];
let res0 = 0;
for (let index = 0; index < arr.length; index++) {
res0 += arr[index]
}
console.log(res0);
const res1 = arr.reduce((prev, cur) => {
return prev + cur
}, 0)
console.log(res1);
- 扁平化数组
const arr2 = [[1, 3], [4, 6], [5, 7]]
const res3 = arr2.reduce(function (prev, curr) {
return [...prev, ...curr]
}, [])
console.log(res3);
- 对象数组转换
const arr3 = [
{ id: 1 },
{ id: 10 },
{ id: 100 },
{ id: 1000 },
{ id: 10000 },
]
const res4 = arr3.reduce((prev, curr) => {
prev[curr.id] = curr
return prev
}, {})
console.log(res4);
- 根据属性分类
const student = [
{ name: 'tom', age: 10, city: 'beijing' },
{ name: 'jay', age: 10, city: 'beijing' },
{ name: 'bill', age: 10, city: 'beijing' },
{ name: 'lily', age: 12, city: 'shanghai' },
{ name: 'lucy', age: 10, city: 'shenzhen' },
{ name: 'jack', age: 5, city: 'guangzhou' },
{ name: 'jerry', age: 7, city: 'hangzhou' },
]
function groupBy(data, key) {
return data.reduce(function (prev, curr) {
if (!prev[curr[key]]) {
prev[curr[key]] = [curr]
} else {
prev[curr[key]].push(curr)
}
return prev
}, {})
}
console.log(groupBy(student, 'city'))
console.log(groupBy(student, 'age'))
- 数组去重
const numbers = [1, 1, 12, 1, 4, 23, 5, 32, 5, 6]
console.log(Array.from(new Set(numbers)));
console.log(numbers.reduce((prev, curr) => {
prev.includes(curr) ? [...prev] : prev.push(curr)
return prev
}, []));
- 管道函数,上一个函数的返回值作为下一个函数的参数
const f1 = function (x) {
return x * 2
}
const f2 = function (x) {
return (x + 2) * 3 + 3
}
const pipe = (...funcs) => input => funcs.reduce((prev, fn) => fn(prev), input)
console.log(pipe(f1, f2)(2));
实际上ES还提供了很多关于数组查找遍历的函数,这里就不再做介绍了,有兴趣的可以查看一下官方文档。