JavaScript数组常用的方法有哪些?map、filter、reduce 的区别和使用场景是什么?

news2025/2/22 15:46:10

JavaScript数组常用的方法有哪些?map、filter、reduce 的区别和使用场景是什么?

JavaScript 数组常用方法

JavaScript 数组有很多实用的方法,以下先简单介绍一些常见的基础方法,再重点讲解 mapfilterreduce 这三个高阶函数。

1. 基础常用方法
push()pop()
  • push():就像往一个箱子里放东西,它会把一个或多个元素添加到数组的末尾,然后返回新数组的长度。
  • pop():类似于从箱子里拿出最上面的东西,它会移除数组的最后一个元素,并返回这个被移除的元素。
let fruits = ['apple', 'banana'];
// 使用 push() 添加元素
let newLength = fruits.push('cherry');
console.log(newLength); // 输出: 3
console.log(fruits); // 输出: ['apple', 'banana', 'cherry']

// 使用 pop() 移除元素
let removedFruit = fruits.pop();
console.log(removedFruit); // 输出: 'cherry'
console.log(fruits); // 输出: ['apple', 'banana']
unshift()shift()
  • unshift():好比在箱子最前面插入东西,它会把一个或多个元素添加到数组的开头,然后返回新数组的长度。
  • shift():如同从箱子最前面拿走东西,它会移除数组的第一个元素,并返回这个被移除的元素。
let numbers = [2, 3];
// 使用 unshift() 添加元素
let newLength2 = numbers.unshift(1);
console.log(newLength2); // 输出: 3
console.log(numbers); // 输出: [1, 2, 3]

// 使用 shift() 移除元素
let removedNumber = numbers.shift();
console.log(removedNumber); // 输出: 1
console.log(numbers); // 输出: [2, 3]
splice()

splice() 就像一个“数组外科医生”,它可以删除、替换或插入元素。它接收三个参数,第一个是开始操作的索引,第二个是要删除的元素个数,后面还可以跟要插入的元素。

let colors = ['red', 'green', 'blue'];
// 删除元素
colors.splice(1, 1);
console.log(colors); // 输出: ['red', 'blue']

// 插入元素
colors.splice(1, 0, 'yellow');
console.log(colors); // 输出: ['red', 'yellow', 'blue']

// 替换元素
colors.splice(1, 1, 'orange');
console.log(colors); // 输出: ['red', 'orange', 'blue']

mapfilterreduce 的区别和使用场景

1. map()
  • 区别map 就像是一个“加工厂”,它会遍历数组中的每个元素,对每个元素执行你提供的函数,然后把处理后的结果组成一个新数组返回。新数组的长度和原数组一样,只是每个元素都经过了处理。
  • 使用场景:当你需要对数组中的每个元素进行某种转换时,就可以使用 map。比如把数组中的每个数字都乘以 2。
let numbers = [1, 2, 3];
// 使用 map 将每个数字乘以 2
let newNumbers = numbers.map(function(num) {
    return num * 2;
});
console.log(newNumbers); // 输出: [2, 4, 6]
2. filter()
  • 区别filter 类似于一个“筛选器”,它会遍历数组中的每个元素,对每个元素执行你提供的函数,根据函数返回的布尔值来决定是否保留该元素。如果返回 true,则该元素会被保留到新数组中;如果返回 false,则该元素会被过滤掉。
  • 使用场景:当你需要从数组中筛选出符合某种条件的元素时,就可以使用 filter。比如从数组中找出所有大于 5 的数字。
let numbers2 = [3, 6, 8, 2];
// 使用 filter 找出大于 5 的数字
let filteredNumbers = numbers2.filter(function(num) {
    return num > 5;
});
console.log(filteredNumbers); // 输出: [6, 8]
3. reduce()
  • 区别reduce 就像一个“累加器”或者“合并器”,它会遍历数组中的每个元素,对每个元素执行你提供的函数,并且会把上一次计算的结果传递给下一次计算。最后返回一个最终的结果。它接收两个参数,第一个是一个回调函数,第二个是初始值(可选)。
  • 使用场景:当你需要对数组中的元素进行累加、合并等操作时,就可以使用 reduce。比如计算数组中所有数字的总和。
let numbers3 = [1, 2, 3, 4];
// 使用 reduce 计算数组元素的总和
let sum = numbers3.reduce(function(accumulator, currentValue) {
    return accumulator + currentValue;
}, 0);
console.log(sum); // 输出: 10

总结来说,map 用于元素转换,filter 用于元素筛选,reduce 用于元素合并或累加。

**在实际项目中,map、filter、reduce 方法通常如何搭配使用?
**
在实际项目中,mapfilterreduce 这三个数组方法经常搭配使用,以实现复杂的数据处理和转换。下面通过不同的实际场景示例,展示它们的搭配使用方式。

场景一:数据筛选与转换后求和

假设你有一个电商项目,需要计算所有已付款商品的总价。商品列表是一个包含多个商品对象的数组,每个商品对象有 price(价格)和 isPaid(是否付款)两个属性。

// 模拟商品列表
const products = [
    { id: 1, price: 20, isPaid: true },
    { id: 2, price: 30, isPaid: false },
    { id: 3, price: 15, isPaid: true },
    { id: 4, price: 40, isPaid: true }
];

// 步骤 1:使用 filter 筛选出已付款的商品
const paidProducts = products.filter(product => product.isPaid);

// 步骤 2:使用 map 提取已付款商品的价格
const paidPrices = paidProducts.map(product => product.price);

// 步骤 3:使用 reduce 计算已付款商品的总价
const totalPrice = paidPrices.reduce((acc, price) => acc + price, 0);

console.log(totalPrice); // 输出: 75

在这个例子中,首先使用 filter 方法筛选出已付款的商品,得到一个只包含已付款商品的新数组。然后使用 map 方法从这个新数组中提取出每个商品的价格,形成一个只包含价格的数组。最后使用 reduce 方法对这个价格数组进行累加,得到已付款商品的总价。

场景二:数据转换与筛选后统计数量

假设你在开发一个博客系统,需要统计所有发布状态为“已发布”且阅读量大于 100 的文章数量。文章列表是一个包含多个文章对象的数组,每个文章对象有 status(状态)和 views(阅读量)两个属性。

// 模拟文章列表
const articles = [
    { title: '文章1', status: 'published', views: 120 },
    { title: '文章2', status: 'draft', views: 80 },
    { title: '文章3', status: 'published', views: 150 },
    { title: '文章4', status: 'published', views: 50 }
];

// 步骤 1:使用 map 转换文章对象为是否符合条件的布尔值
const isQualified = articles.map(article => article.status === 'published' && article.views > 100);

// 步骤 2:使用 filter 筛选出符合条件的布尔值(即 true)
const qualifiedArticles = isQualified.filter(Boolean);

// 步骤 3:使用 reduce 统计符合条件的文章数量
const count = qualifiedArticles.reduce((acc) => acc + 1, 0);

console.log(count); // 输出: 2

这里先使用 map 方法将文章对象转换为布尔值,表示该文章是否符合“已发布且阅读量大于 100”的条件。接着使用 filter 方法筛选出布尔值为 true 的元素,得到一个只包含 true 的数组。最后使用 reduce 方法对这个数组进行累加,统计出符合条件的文章数量。

场景三:数据分组与统计

假设你在处理一个学生成绩数据,需要统计每个班级的总成绩。学生成绩数据是一个包含多个学生对象的数组,每个学生对象有 class(班级)和 score(成绩)两个属性。

// 模拟学生成绩数据
const students = [
    { name: '张三', class: 'A', score: 80 },
    { name: '李四', class: 'B', score: 90 },
    { name: '王五', class: 'A', score: 70 },
    { name: '赵六', class: 'B', score: 85 }
];

// 使用 reduce 进行分组和统计
const classScores = students.reduce((acc, student) => {
    const { class: className, score } = student;
    if (!acc[className]) {
        acc[className] = 0;
    }
    acc[className] += score;
    return acc;
}, {});

console.log(classScores); // 输出: { A: 150, B: 175 }

在这个例子中,主要使用 reduce 方法完成数据的分组和统计。reduce 的初始值是一个空对象 {},在回调函数中,根据学生的班级对成绩进行分组累加,最终得到每个班级的总成绩。如果需要对每个班级的总成绩进行进一步处理,比如转换为数组形式,可以结合 map 方法:

const classScoreArray = Object.entries(classScores).map(([className, totalScore]) => ({
    class: className,
    totalScore
}));

console.log(classScoreArray); 
// 输出: [ { class: 'A', totalScore: 150 }, { class: 'B', totalScore: 175 } ]

通过以上场景可以看出,mapfilterreduce 方法相互配合,能够高效地完成各种复杂的数据处理任务。在实际应用中,可以根据具体需求灵活组合使用这些方法。

在实际项目中,map、filter、reduce 方法的性能有何区别?
在实际项目中,mapfilterreduce 都是 JavaScript 数组的高阶函数,它们在性能方面存在一些区别,下面从时间复杂度、内存使用、实际应用场景等方面详细分析。

时间复杂度

  • map 方法map 方法会遍历数组中的每个元素,对每个元素执行一次提供的回调函数,并将结果存储在一个新数组中。因此,map 方法的时间复杂度是 O ( n ) O(n) O(n),其中 n n n 是数组的长度。因为它只需要对数组进行一次线性遍历。
const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(num => num * num);
  • filter 方法filter 方法同样会遍历数组中的每个元素,根据回调函数的返回值决定是否将该元素保留在新数组中。所以,filter 方法的时间复杂度也是 O ( n ) O(n) O(n),需要对数组进行一次完整的遍历。
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);
  • reduce 方法reduce 方法会对数组中的每个元素执行一次回调函数,并将上一次回调的结果传递给下一次回调。其时间复杂度同样是 O ( n ) O(n) O(n),因为它也需要遍历数组一次。
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);

内存使用

  • map 方法map 方法会创建一个与原数组长度相同的新数组,新数组中的每个元素是原数组对应元素经过处理后的结果。因此,它的内存使用主要取决于原数组的长度和处理后元素的大小。如果处理后的元素大小与原元素相近,那么内存使用会增加与原数组大小相近的空间。
const largeArray = new Array(1000000).fill(1);
const newArray = largeArray.map(num => num * 2);
  • filter 方法filter 方法创建的新数组长度通常小于或等于原数组长度,具体取决于过滤条件。如果大部分元素都满足过滤条件,那么内存使用会接近原数组大小;如果只有少数元素满足条件,内存使用会相应减少。
const largeArray = new Array(1000000).fill(1);
const filteredArray = largeArray.filter(num => num % 2 === 0);
  • reduce 方法reduce 方法不会创建新数组,而是返回一个单一的值或对象。因此,它的内存使用相对较小,主要取决于最终结果的大小。
const largeArray = new Array(1000000).fill(1);
const sum = largeArray.reduce((acc, num) => acc + num, 0);

实际应用场景对性能的影响

  • 简单转换场景:如果只是对数组中的每个元素进行简单的转换,使用 map 方法是最合适的。因为它的逻辑清晰,性能也比较稳定。例如,将数组中的每个数字转换为其平方值。
const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(num => num * num);
  • 筛选场景:当需要从数组中筛选出符合特定条件的元素时,使用 filter 方法。它可以避免不必要的元素处理,提高性能。例如,从数组中筛选出所有偶数。
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);
  • 聚合场景:如果需要对数组元素进行聚合操作,如求和、求平均值等,使用 reduce 方法。它可以在一次遍历中完成聚合,避免多次遍历数组。例如,计算数组中所有元素的总和。
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);

链式调用时的性能考虑

在实际项目中,经常会链式调用这三个方法。在链式调用时,每次调用都会创建一个新的中间数组(mapfilter),这会增加内存使用和处理时间。可以考虑使用 reduce 方法来合并多个操作,减少中间数组的创建,提高性能。

// 链式调用 map 和 filter
const numbers = [1, 2, 3, 4, 5];
const result1 = numbers.map(num => num * 2).filter(num => num > 5);

// 使用 reduce 合并操作
const result2 = numbers.reduce((acc, num) => {
    const doubled = num * 2;
    if (doubled > 5) {
        acc.push(doubled);
    }
    return acc;
}, []);

综上所述,mapfilterreduce 方法的时间复杂度相同,但在内存使用和适用场景上有所差异。在实际项目中,需要根据具体需求选择合适的方法,以提高代码的性能和效率。

除了 map、filter、reduce 之外,还有哪些常用的数组方法?

除了 mapfilterreduce 之外,JavaScript 数组还有许多其他常用的方法,下面为你详细介绍:

1. 元素添加与删除类

push()pop()
  • push():用于在数组的末尾添加一个或多个元素,并返回新的数组长度。
const fruits = ['apple', 'banana'];
const newLength = fruits.push('cherry', 'date');
console.log(fruits); // 输出: ['apple', 'banana', 'cherry', 'date']
console.log(newLength); // 输出: 4
  • pop():用于移除数组的最后一个元素,并返回该元素。
const fruits = ['apple', 'banana', 'cherry'];
const removedFruit = fruits.pop();
console.log(fruits); // 输出: ['apple', 'banana']
console.log(removedFruit); // 输出: 'cherry'
unshift()shift()
  • unshift():在数组的开头添加一个或多个元素,并返回新的数组长度。
const numbers = [2, 3];
const newLength = numbers.unshift(0, 1);
console.log(numbers); // 输出: [0, 1, 2, 3]
console.log(newLength); // 输出: 4
  • shift():移除数组的第一个元素,并返回该元素。
const numbers = [1, 2, 3];
const removedNumber = numbers.shift();
console.log(numbers); // 输出: [2, 3]
console.log(removedNumber); // 输出: 1
splice()

可以用于删除、插入或替换数组中的元素。它接收三个参数:起始索引、要删除的元素个数、要插入的元素(可选)。

const colors = ['red', 'green', 'blue'];
// 删除元素
colors.splice(1, 1); 
console.log(colors); // 输出: ['red', 'blue']

// 插入元素
colors.splice(1, 0, 'yellow'); 
console.log(colors); // 输出: ['red', 'yellow', 'blue']

// 替换元素
colors.splice(1, 1, 'orange'); 
console.log(colors); // 输出: ['red', 'orange', 'blue']

2. 数组合并与截取类

concat()

用于合并两个或多个数组,并返回一个新数组,原数组不会被修改。

const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [5, 6];
const newArray = arr1.concat(arr2, arr3);
console.log(newArray); // 输出: [1, 2, 3, 4, 5, 6]
slice()

用于截取数组的一部分,并返回一个新数组,原数组不会被修改。它接收两个参数:起始索引和结束索引(可选,不包含该索引对应的元素)。

const numbers = [1, 2, 3, 4, 5];
const slicedArray = numbers.slice(1, 3);
console.log(slicedArray); // 输出: [2, 3]

3. 数组查找与排序类

indexOf()lastIndexOf()
  • indexOf():返回指定元素在数组中第一次出现的索引,如果未找到则返回 -1。
const fruits = ['apple', 'banana', 'cherry', 'banana'];
const index = fruits.indexOf('banana');
console.log(index); // 输出: 1
  • lastIndexOf():返回指定元素在数组中最后一次出现的索引,如果未找到则返回 -1。
const fruits = ['apple', 'banana', 'cherry', 'banana'];
const lastIndex = fruits.lastIndexOf('banana');
console.log(lastIndex); // 输出: 3
find()findIndex()
  • find():返回数组中满足提供的测试函数的第一个元素的值,如果没有找到则返回 undefined
const numbers = [1, 2, 3, 4, 5];
const foundNumber = numbers.find(num => num > 3);
console.log(foundNumber); // 输出: 4
  • findIndex():返回数组中满足提供的测试函数的第一个元素的索引,如果没有找到则返回 -1。
const numbers = [1, 2, 3, 4, 5];
const foundIndex = numbers.findIndex(num => num > 3);
console.log(foundIndex); // 输出: 3
sort()

用于对数组的元素进行排序,默认按照字符串的 Unicode 编码进行排序。可以传入一个比较函数来指定排序规则。

const numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
numbers.sort((a, b) => a - b);
console.log(numbers); // 输出: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

4. 数组转换与迭代类

join()

将数组的所有元素连接成一个字符串,并返回该字符串。可以指定连接符,默认为逗号。

const fruits = ['apple', 'banana', 'cherry'];
const fruitString = fruits.join(' - ');
console.log(fruitString); // 输出: 'apple - banana - cherry'
reverse()

用于颠倒数组中元素的顺序,原数组会被修改。

const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // 输出: [5, 4, 3, 2, 1]
forEach()

对数组的每个元素执行一次提供的函数,没有返回值。

const numbers = [1, 2, 3];
numbers.forEach(num => {
    console.log(num * 2);
});
// 输出: 2
// 输出: 4
// 输出: 6

concat() 方法与 push() 方法有什么区别?

concat()push() 都是 JavaScript 数组中用于添加元素的方法,但它们在功能、使用方式、对原数组的影响以及返回值等方面存在明显区别,下面为你详细介绍:

1. 功能和使用方式

  • concat() 方法:主要用于合并两个或多个数组,它可以接收数组或者单个值作为参数,将这些参数中的元素合并到一个新数组中。concat() 方法不会修改原数组,而是返回一个新的合并后的数组。
const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = 5;

// 合并数组和单个值
const newArray = arr1.concat(arr2, arr3);
console.log(newArray); // 输出: [1, 2, 3, 4, 5]
console.log(arr1); // 输出: [1, 2],原数组未被修改
  • push() 方法:用于在数组的末尾添加一个或多个元素。它直接修改调用该方法的原数组,并且返回新数组的长度。
const arr = [1, 2];
const newLength = arr.push(3, 4);
console.log(arr); // 输出: [1, 2, 3, 4],原数组被修改
console.log(newLength); // 输出: 4

2. 对原数组的影响

  • concat() 方法:不改变原数组,它只是创建并返回一个新的数组,这个新数组包含了原数组和传入参数中的所有元素。原数组保持不变,这在需要保留原始数据的场景中非常有用。
const originalArray = [1, 2];
const anotherArray = [3, 4];
const combinedArray = originalArray.concat(anotherArray);
console.log(originalArray); // 输出: [1, 2]
  • push() 方法:会直接修改调用它的数组,将新元素添加到原数组的末尾。这意味着原数组的内容会发生改变。
const originalArray = [1, 2];
originalArray.push(3);
console.log(originalArray); // 输出: [1, 2, 3]

3. 返回值

  • concat() 方法:返回一个新的数组,这个新数组是原数组和传入参数合并后的结果。
const arr1 = [1, 2];
const arr2 = [3, 4];
const result = arr1.concat(arr2);
console.log(result); // 输出: [1, 2, 3, 4]
  • push() 方法:返回添加元素后数组的新长度。
const arr = [1, 2];
const length = arr.push(3);
console.log(length); // 输出: 3

4. 处理多维数组的方式

  • concat() 方法:对于传入的数组参数,它会将其元素展开并添加到新数组中,而不是将整个数组作为一个元素添加。
const arr1 = [1, 2];
const arr2 = [3, 4];
const result = arr1.concat(arr2);
console.log(result); // 输出: [1, 2, 3, 4]
  • push() 方法:如果传入的是一个数组,它会将整个数组作为一个元素添加到原数组的末尾。
const arr = [1, 2];
const anotherArr = [3, 4];
arr.push(anotherArr);
console.log(arr); // 输出: [1, 2, [3, 4]]

综上所述,concat() 适用于需要合并数组且不改变原数组的场景,而 push() 适用于直接在原数组末尾添加元素并获取新数组长度的场景。

**slice() 和 splice() 方法有什么不同?
**
slice()splice() 是 JavaScript 数组中用于处理数组元素的两个方法,它们在功能、使用方式、对原数组的影响等方面存在明显差异,以下是详细对比:

1. 功能用途

  • slice() 方法:主要用于从原数组中提取一部分元素,创建并返回一个新数组,就像用刀从一块蛋糕上切下一部分,原蛋糕(原数组)不会被改变。常用于获取数组的子集,比如获取数组的前几个元素、中间一段元素等。
  • splice() 方法:功能更强大且灵活,它可以用于删除、插入或替换数组中的元素,相当于对原数组进行“手术”,会直接修改原数组。常用于需要对数组进行元素的增删改操作的场景。

2. 语法和参数

  • slice() 方法
    • 语法:arr.slice([begin[, end]])
    • 参数:
      • begin(可选):提取起始位置的索引,默认为 0。如果为负数,则从数组末尾开始计算。
      • end(可选):提取结束位置的索引(不包含该索引对应的元素)。如果省略,则提取到数组末尾;如果为负数,则从数组末尾开始计算。
const fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
const slicedFruits = fruits.slice(1, 3);
console.log(slicedFruits); // 输出: ['banana', 'cherry']
console.log(fruits); // 输出: ['apple', 'banana', 'cherry', 'date', 'elderberry'],原数组未改变
  • splice() 方法
    • 语法:arr.splice(start[, deleteCount[, item1[, item2[, ...]]]])
    • 参数:
      • start:操作起始位置的索引。
      • deleteCount(可选):要删除的元素个数。如果省略,则从 start 位置开始删除到数组末尾;如果为 0,则不删除元素。
      • item1, item2, ...(可选):要插入到数组中的元素,从 start 位置开始插入。
const fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
// 删除元素
const removedFruits = fruits.splice(1, 2);
console.log(removedFruits); // 输出: ['banana', 'cherry']
console.log(fruits); // 输出: ['apple', 'date', 'elderberry'],原数组被修改

// 插入元素
fruits.splice(1, 0, 'fig', 'grape');
console.log(fruits); // 输出: ['apple', 'fig', 'grape', 'date', 'elderberry']

// 替换元素
fruits.splice(2, 1, 'honeydew');
console.log(fruits); // 输出: ['apple', 'fig', 'honeydew', 'date', 'elderberry']

3. 对原数组的影响

  • slice() 方法:不会修改原数组,它只是从原数组中提取元素并返回一个新数组,原数组保持不变。这在需要保留原始数据,同时获取部分数据的场景中非常有用。
  • splice() 方法:会直接修改原数组,根据传入的参数进行元素的删除、插入或替换操作。原数组的内容会发生改变,适用于需要对数组进行实时修改的场景。

4. 返回值

  • slice() 方法:返回一个新数组,包含从原数组中提取的元素。
  • splice() 方法:返回一个数组,包含从原数组中删除的元素。如果没有删除元素,则返回一个空数组。

综上所述,slice() 主要用于提取数组元素,不改变原数组;而 splice() 用于对数组进行增删改操作,会改变原数组。在实际使用中,应根据具体需求选择合适的方法。

在实际项目中,map、filter、reduce 如何选用方法?

在实际项目中,mapfilterreduce 是 JavaScript 数组非常实用的高阶函数,它们各自有独特的用途,选用时需要依据具体的业务需求,下面详细介绍选用这些方法的思路和实际场景示例。

1. map 方法

适用场景

当你需要对数组中的每个元素进行相同的转换操作,并且希望得到一个新数组,新数组的长度与原数组相同,只是元素的值经过了处理,这时就可以使用 map 方法。简单来说,就是“一个换一个”的操作。

示例

在一个电商项目中,有一个商品价格数组,需要将每个商品的价格增加 10%。

const prices = [100, 200, 300];
const newPrices = prices.map(price => price * 1.1);
console.log(newPrices); 
// 输出: [110, 220, 330]

这里使用 map 方法对 prices 数组中的每个元素乘以 1.1,得到一个新的 newPrices 数组。

2. filter 方法

适用场景

当你需要从数组中筛选出符合特定条件的元素,形成一个新数组,新数组的长度可能小于原数组,这时就适合使用 filter 方法。可以把它想象成一个“筛子”,只让符合条件的元素通过。

示例

在一个学生成绩管理系统中,有一个学生成绩数组,需要筛选出成绩大于 80 分的学生。

const scores = [70, 85, 90, 60, 88];
const highScores = scores.filter(score => score > 80);
console.log(highScores); 
// 输出: [85, 90, 88]

这里使用 filter 方法筛选出 scores 数组中大于 80 的元素,组成新的 highScores 数组。

3. reduce 方法

适用场景

reduce 方法适用于对数组元素进行聚合操作,将数组中的多个元素合并成一个单一的值或对象。常见的聚合操作包括求和、求平均值、统计数量、分组等。

示例
  • 求和:计算一个数组中所有数字的总和。
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); 
// 输出: 15

这里 reduce 方法从初始值 0 开始,依次将数组中的元素累加到 acc 中,最终得到总和。

  • 分组:有一个学生信息数组,需要根据学生的班级进行分组。
const students = [
    { name: '张三', class: 'A' },
    { name: '李四', class: 'B' },
    { name: '王五', class: 'A' }
];
const groupedStudents = students.reduce((acc, student) => {
    const className = student.class;
    if (!acc[className]) {
        acc[className] = [];
    }
    acc[className].push(student);
    return acc;
}, {});
console.log(groupedStudents); 
// 输出: { A: [ { name: '张三', class: 'A' }, { name: '王五', class: 'A' } ], B: [ { name: '李四', class: 'B' } ] }

这里使用 reduce 方法将学生按班级分组,最终得到一个对象,对象的键是班级名,值是该班级的学生数组。

4. 组合使用

在实际项目中,还可能会组合使用这三个方法。例如,先使用 filter 筛选出符合条件的元素,再使用 map 对筛选后的元素进行转换,最后使用 reduce 进行聚合。

示例

有一个商品数组,需要筛选出价格大于 50 的商品,将这些商品的价格增加 10%,然后计算这些商品的总价。

const products = [
    { name: '商品1', price: 30 },
    { name: '商品2', price: 60 },
    { name: '商品3', price: 80 }
];
const totalPrice = products
   .filter(product => product.price > 50)
   .map(product => product.price * 1.1)
   .reduce((acc, price) => acc + price, 0);
console.log(totalPrice); 
// 输出: 154

这里先使用 filter 筛选出价格大于 50 的商品,再用 map 对筛选后的商品价格增加 10%,最后用 reduce 计算总价。

综上所述,选用 mapfilter 还是 reduce 方法,关键在于明确业务需求是进行元素转换、筛选还是聚合,以及是否需要组合使用这些方法来完成更复杂的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2303493.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vim修改只读文件

现象 解决方案 对于有root权限的用户,在命令行输入 :wq! 即可强制保存退出

【DeepSeek】本地部署,保姆级教程

deepseek网站链接传送门:DeepSeek 在这里主要介绍DeepSeek的两种部署方法,一种是调用API,一种是本地部署。 一、API调用 1.进入网址Cherry Studio - 全能的AI助手选择立即下载 2.安装时位置建议放在其他盘,不要放c盘 3.进入软件后…

NCRE证书构成:全国计算机等级考试证书体系详解

全国计算机等级考试(NCRE)证书体系为中学生提供了一个系统学习和提升计算机能力的平台。本文将详细介绍 NCRE 证书的构成,帮助中学生了解 NCRE 证书的级别和内容,规划未来职业发展。 一、NCRE 证书体系概述 NCRE 证书共分为四个级…

如何在WPS打开的word、excel文件中,使用AI?

1、百度搜索:Office AI官方下载 或者直接打开网址:https://www.office-ai.cn/static/introductions/officeai/smartdownload.html 打开后会直接提示开始下载中,下载完成后会让其选择下载存放位置: 选择位置,然后命名文…

【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})

代理模式 代理模式是一种结构型设计模式,它提供了一种替代访问的方法,即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下,增加额外的功能,如权限控制、日志记录等。 静态代理 静态代理是指创建的或特…

《A++ 敏捷开发》- 16 评审与结对编程

客户:我们的客户以银行为主,他们很注重质量,所以一直很注重评审。他们对需求评审、代码走查等也很赞同,也能找到缺陷,对提升质量有作用。但他们最困惑的是通过设计评审很难发现缺陷。 我:你听说过敏捷的结对…

NutUI内网离线部署

文章目录 官网拉取源代码到本地仓库修改源代码打包构建nginx反向代理部署访问内网离线地址 在网上找了一圈没有写NutUI内网离线部署的文档,花了1天时间研究下,终于解决了。 对于有在内网离线使用的小伙伴就可以参考使用了 如果还是不会联系UP主:QQ:10927…

【实战篇】【深度介绍 DeepSeek R1 本地/私有化部署大模型常见问题及解决方案】

引言 大家好!今天我们来聊聊 DeepSeek R1 的本地/私有化部署大模型。如果你正在考虑或者已经开始了这个项目,那么这篇文章就是为你准备的。我们会详细探讨常见问题及其解决方案,帮助你更好地理解和解决在部署过程中可能遇到的挑战。准备好了…

Qt学习(六) 软件启动界面 ,注册表使用 ,QT绘图, 视图和窗口绘图,Graphics View绘图框架:简易CAD

一 软件启动界面 注册表使用 知识点1:这样创建的界面是不可以拖动的,需要手动创建函数来进行拖动,以下的3个函数是从父类继承过来的函数 virtual void mousePressEvent(QMouseEvent *event);virtual void mouseReleaseEvent(QMouseEvent *eve…

java练习(36)

ps:题目来自力扣 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。 class Solution {publ…

【Linux网络编程】IP协议格式,解包步骤

目录 解析步骤 1.版本字段(大小:4比特位) 2.首部长度(大小:4比特位)(单位:4字节) 🍜细节解释: 3.服务类型(大小:8比特…

Unity 位图字体

下载Bitmap Font Generator BMFont - AngelCode.com 解压后不用安装直接双击使用 提前设置 1、设置Bit depth为32 Options->Export options 2、清空所选字符 因为我们将在后边导入需要的字符。 Edit->Select all chars 先选择所有字符 Edit->Clear all chars i…

Linux 网络与常用操作(适合开发/运维/网络工程师)

目录 OSI 七层协议简介 应用层 传输层 Linux 命令!!! 1. ifconfig 命令 简介 1. 查看网络地址信息 2. 指定开启、或者关闭网卡 3. 修改、设置 IP 地址 4. 修改机器的 MAC 地址信息 5. 永久修改网络设备信息 2. route 路由命令 …

linux 安装启动zookeeper全过程及遇到的坑

1、下载安装zookeeper 参考文章:https://blog.csdn.net/weixin_48887095/article/details/132397448 2、启动失败 1、启动失败JAVA_HOME is not set and java could not be found in PATH 已安装 JAVA 配置了JAVA_HOME,还是报错解决方法:参考&#xf…

MySQL数据库——表的约束

1.空属性(null/not null) 两个值:null(默认的)和not null(不为空) 数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法…

ArcGIS Pro进行坡度与坡向分析

在地理信息系统中,坡度分析是一项至关重要的空间分析方法,旨在精确计算地表或地形的坡度,为地形特征识别、土地资源规划、环境保护、灾害预警等领域提供科学依据。本文将详细介绍如何利用ArcGIS Pro这一强大的地理信息系统软件,进…

【MySQL常见疑难杂症】MySQL数据库底层图例

● Connectors(连接者)​:指的是不同语言中与SQL的交互,从图3-1中可以看到目前流行的语言都支持MySQL客户端连接。 ● Connection Pool(连接池)​:管理缓冲用户连接、线程处理等需要缓存的需求。…

谈谈对线程的认识

面对这样的一个多核CPU时代, 实现并发编程是刚需. 多进程实现并发编程, 效果是特别理想的. 但是, 多线程编程模型有一个明显的缺点, 就是进程太重了, 效率不高. 创建一个进程, 消耗时间比较多. 销毁一个进程, 消耗时间也比较多. 调度一个进程, 消耗时间也比较多. 这里的时…

无人机遥控器接口作用详解!

USB接口: 功能:USB接口是一种通用串行总线接口,用于连接外部设备,如手机、平板、电脑或充电设备。在无人机遥控器上,USB接口通常用于数据传输和充电。 应用:用户可以通过USB接口将遥控器与电脑连接&#…

【数据分析】1 认识数据分析

一、课程核心内容结构 1. 课程定位 商业数据分析导论课:旨在为初学者奠定扎实的基础,介绍数据分析的基本概念、方法和应用场景。后续模块:包括职业发展路径、技能要求等深入内容,帮助学习者规划未来的职业道路。目标群体&#x…