JS数组遍历方法:forEach、map、filter、reduce、some、every,find,findIndex....

294 阅读5分钟

1.for循环

例子

const array =  [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
    console.log(array[i]);
}

2. for-of

for...of 语句用于遍历可迭代对象 ,是ES6新增的一种循环语法,它可以用于遍历数组、字符串、Map、Set等可迭代对象。与传统的for循环不同,for...of循环语句本身不包含初始化变量、循环条件和迭代器,而是直接遍历迭代对象中的每个元素

for…of 与数组
// array
const students = ['John', 'Sara', 'Jack'];
// using for...of
for ( let element of students ) {
    // display the values
    console.log(element);// John Sara Jack
}
for…of 与字符串
// string
const string = 'code';
// using for...of loop
for (let i of string) {
    console.log(i);// c o d e
}
for…of 与 Set
const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)])//[2, 3, 4, 5, 6, 7, 32]
// define Set
const set = new Set([1, 2, 3,1,3,5,3]);
// looping through Set
for (let i of set) {
    console.log(i);//1 2 3 5
}
for…of 与 Map
/ define Map
let map = new Map();
// inserting elements
map.set('name', 'Jack');
map.set('age', '27');
// looping through Map
for (let [key, value] of map) {
    console.log(key + '- ' + value);//name- Jack  age- 27
}

3. forEach

参数 element正在处理的当前元素。、index当前元素的索引、array被遍历的数组

返回值: undefined

是否改变原数组: 可以改变原数组

使用时机: 用于对数组中的每个元素执行指定的操作

除非抛出异常,否则没有办法停止或中断,不能使用break 会报错

不可以直接修改元素,但是可以修改元素的属性

const numbers = [1, 2, 3, 4, 5];
const value = numbers.forEach((item, index, arr) => {
    console.log(item, index, arr)
})
numbers.forEach((item, index, arr) => {
	item = item * 2; // 这里只是修改了形参item的值,并不会修改原数组
})
console.log(numbers);//[1, 2, 3, 4, 5];
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((item, index, arr) => {
    arr[index] = item * 2; // 通过修改属性修改原数组值
})
console.log(numbers);//[2, 4, 6, 8, 10]

forEach终止循环-后续代码不在执行

try{
    const numbers = [1, 2, 3, 4, 5];
    numbers.forEach((item, index, arr) => {

        if(item==2){
            throw new Error('请选择')
        }
        console.log(item);//1
    })
}catch (e){
    console.log(e);
}

4.some

如果有一个元素符合条件,则循环不再继续,直接返回 true,否则返回 false

const numbers = [1, 2, 3, -4, 5];
const hasNegative = numbers.some(num => num < 0);
console.log(hasNegative);//true

5. every

用于检查数组中的所有元素是否都满足指定的条件

如果有一个元素符合条件,则循环不再继续,直接返回 false,否则返回 true

const numbers = [1, 2, 3, 4, 5];
const allPositive = numbers.every(num => num > 0);
console.log(allPositive); // true

6.filter

用于根据指定的条件筛选出数组中满足条件的元素

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num>3);
console.log(evenNumbers);  // [4, 5]

7.find

用于在数组中查找满足指定条件的第一个元素

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.find(num => num>3);
console.log(evenNumbers);  // 4

8.findIndex

find类似。只不过是查找元素下标,没有找到符合条件的就返回 -1

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.findIndex(num => num>3);
console.log(evenNumbers);  // 3 是数字4的下标

9.findLast

findLast 方法用于在数组中从后往前查找满足条件的元素,并返回该元素。和 find 方法类似,但是从数组的末尾开始搜索,找到满足条件的最后一个元素

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.findLast(num => num>3);
console.log(evenNumbers);  // 5

10. findLastIndex

findLastIndex 方法用于在数组中从后往前查找满足条件的元素,并返回该元素的索引。和 findIndex 方法类似,但是从数组的末尾开始搜索,找到满足条件的最后一个元素的索引。

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.findLastIndex(num => num>3);
console.log(evenNumbers);  // 4 是数字5的下标

11. map

返回的数据不符合我们的要求,可以使用 map 把数据处理成我们想要的

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.map(num => num+1);
console.log(evenNumbers);  // [2, 3, 4, 5, 6]

12 reduce

参数: 接收两个参数

  • 参数一:是一个函数,函数有四个参数,分别是:上一次的值,当前值,当前值的索引,数组
  • 参数二:可选的基底值,可以设置一个数字参与求和运算

返回值: 最终累积结果:reduce方法返回最终的累积结果,可以是任意数据类型,如数字、字符串、对象或数组。

是否改变原数组: 不改变原数组

使用时机: 用于各种集合处理和聚合的情况,可以根据需求定义自定义的合并操作

语法

arr.reduce(function(prev,cur,index,arr){
...
}, init);

例子

const count = [0, 1, 2, 3, 4].reduce((prev, curr, index, array) => prev + curr);
console.log(count); // 10

应用1: 求和

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((prev, curr, index, array) => prev + curr, 1);
console.log(sum); // 16

应用2: 数组扁平化

const nestedArray = [[1, 2], [3, 4], [5, 6]];
const flattenedArray = nestedArray.reduce((acc, curr) => acc.concat(curr), []);
console.log(flattenedArray); // [1, 2, 3, 4, 5, 6]

应用3: 数组元素的最大值和最小值

const numbers = [10, 5, 8, 3, 12];
const maxNumber = numbers.reduce((max, curr) => Math.max(max, curr), Number.MIN_SAFE_INTEGER);
console.log(maxNumber); // 12

const minNumber = numbers.reduce((min, curr) => Math.min(min, curr), Number.MAX_SAFE_INTEGER);
console.log(minNumber); // 3

应用4:求平均值

const scores = [85, 90, 76, 92, 88];
const averageScore = scores.reduce((sum, curr) => sum + curr, 0) / scores.length;
console.log(averageScore); // 86.2

13 reduceRight

reduceRight 和 reduce 都是对数组元素进行累计操作,这两个之间的区别在于迭代方向,reduce 从数组左侧开始迭代,reduceRight从数组右侧。

reduceRight 需要从数组的尾部开始处理元素以满足特定的需求,如字符串反转,处理树结构等...

应用1: 字符串反转

const str = 'Hello, World!';
const reversedStr = [...str].reduceRight((acc, curr) => acc + curr, '');
console.log(reversedStr); // "!dlroW ,olleH"

应用2: 扁平化树结构

const tree = {
    name: 'A',
    children: [
        {
            name: 'B',
            children: [
                { name: 'D', children: [] },
                { name: 'E', children: [] }
            ]
        },
        { name: 'C', children: [] }
    ]
};

function flattenTree(tree) {
    return [tree, ...tree.children.reduceRight((acc, curr) => {
        return [...acc, ...flattenTree(curr)];
    }, [])];
}

const flattenedTree = flattenTree(tree);
console.log(flattenedTree);
// [
//   { name: 'A', children: [...] },
//   { name: 'B', children: [...] },
//   { name: 'D', children: [] },
//   { name: 'E', children: [] },
//   { name: 'C', children: [] }
// ]

总结

  1. 特定的循环,并且需要中断和跳过可使用 for
  2. 无需返回值可使用 forEach、for...of
  3. 检查是否满足指定条件而无需使用元素可使用 some、every
  4. 筛选符合条件的元素可使用filter、find、findLast
  5. 找到符合条件的元素索引可使用 findIndex、findLastIndex
  6. 需要对不符合展示条件的数据继续再处理时可使用map
  7. 需要依赖数组元素上次结果,如累计可使用 reduce、reduceRight