如何在 JavaScript 中执行常见的操作,其中可能使用循环,使用 map()、filter()、reduce() 和 find()
循环通常用于在任何编程语言中对数组执行操作:给定一个数组,您可以迭代其元素并执行计算。
让我们看看如何选择常见需求并使用**函数式编程**方法执行它们,而不使用循环。
注意:我不推荐其中一种方法。我只是想介绍执行相同操作的不同方式,并可能向您介绍一些以前可能从未使用过的新函数。
map
、filter
、reduce
、find
这些是三个非常强大的数组函数:
map
返回一个与原始数组具有相同长度的数组。filter
如其名所示,返回比原始数组少的项目的数组。reduce
返回一个单个值(或对象)。find
返回数组中满足条件的第一个项目。
map
、filter
和 reduce
在 ES5 中引入,因此您可以安全地在每个浏览器中使用它们的实现已经多年了。
find
在 ES6/ES2015 中引入。
它们提供了一种更加声明性的方法,而不是命令性的方法(描述应该发生的情况,而不是写出应该发生的每个微小处理)。
使用 map
在每个元素上执行某些操作
使用循环的示例如下:
const performSomething = (item) => {
// ...
return item;
};
const items = ['a', 'b', 'c'];
items.forEach((item) => {
performSomething(item);
});
使用声明性方法,您告诉 JavaScript 在每个元素上执行某些操作:
const items = ['a', 'b', 'c'];
const newArray = items.map((item) => performSomething(item));
这将生成一个新数组,而不是编辑原始数组(我们称之为不可变性)。
由于在 map 回调函数中使用了单个函数,我们可以将示例重写为:
const items = ['a', 'b', 'c'];
const newArray = items.map(performSomething);
在数组中查找单个元素
有时您需要在数组中查找特定的项目并返回它。
使用循环可以这样做:
const items = [
{ name: 'a', content: { /* ... */ }},
{ name: 'b', content: { /* ... */ }},
{ name: 'c', content: { /* ... */ }}
];
for (const item of items) {
if (item.name === 'b') {
return item;
}
}
这是使用 find()
(ES6+)的非循环版本:
const b = items.find((item) => item.name === 'b');
这是使用 filter()
(ES5+)的相同功能:
const b = items.filter((item) => item.name === 'b').shift();
shift() 返回数组中的第一个项目,如果数组为空则不会引发错误(在这种情况下返回
undefined
)。
注意:shift() 会改变数组,但它改变的是由 filter() 返回的数组,而不是原始数组。如果这听起来不可接受,您可以检查数组是否不为空,并使用 b[0]
获取第一个项目。
出于学习目的(实际上没有太多意义),以下是使用 reduce()
实现相同功能:
const items = [
{ name: 'a', content: { /* ... */ }},
{ name: 'b', content: { /* ... */ }},
{ name: 'c', content: { /* ... */ }}
];
const b = items.reduce((result, item) => {
if (item.name === 'b') { result = item; }
return result;
}, null);
filter()
和 reduce()
将遍历所有数组项,而 find()
将更快一些。
遍历数组以计算每个项目的属性计数
使用 reduce()
从数组中获取单个值。例如,对项的 content.value
属性求和:
const items = [
{ name: 'a', content: { value: 1 }},
{ name: 'b', content: { value: 2 }},
{ name: 'c', content: { value: 3 }}
];
使用循环:
let count = 0;
for (const item of items) {
count += item.content.value;
}
可以写为:
const count = items.reduce((result, { content: { value } }) => result + value, 0);