什么是高阶函数?
高阶函数是一个以一个函数为参数或返回一个函数的函数。这种类型的函数在许多编程语言中都有实现,包括Go、JavaScript、Python等;而且它们有成为面试中的一个问题的趋势。很多时候,我和开发人员谈起这个概念,他们对这个名字并不熟悉,尽管他们每天都在不知不觉地使用它,所以我决定用一篇文章来介绍这个话题,让我们都清楚它们是什么以及它们如何发挥作用。
由于这个话题在多种编程语言中广泛使用,我将提供JavaScript和Python的代码样本。
一些简单的例子
让我们来看看高阶函数的一些简单例子,以进入这个话题并与代码打交道,然后我们将推进到构建一些我们使用的流行函数,这些函数是高阶函数的例子。
以一个函数作为参数
首先让我们建立一个非常简单的函数,名为doOperation ,它需要3个参数。
- 函数操作
- 数字1
- 数字2
此外,我们将创建一个名为sumBothNumbers 的操作,它将简单地返回两个数字的总和。
Python。
def doOperation(operation, number1, number2):
return operation(number1, number2)
def sumBothNumbers(number1, number2):
return number1 + number2
doOperation(sumBothNumbers, 3, 5)
------------
Output
------------
8
JavaScript。
function doOperation(operation, number1, number2) {
return operation(number1, number2)
}
function sumBothNumbers(number1, number2) {
return number1 + number2
}
doOperation(sumBothNumbers, 3, 5)
------------
Output
------------
8
虽然在这种特殊情况下,有doOperation 函数似乎是多余的,甚至是错误的,但在有些情况下它是有用的,doOperation 函数可以是一个库的一部分,例如,我们可以用我们自己的操作来扩展。
返回一个函数
接下来,我们将建立一个高阶函数,它将返回一个函数。我们的函数将被称为multiplyBy ,它将接受一个数字作为参数,并返回一个将其输入乘以该数字的函数。
Python。
def multiplyBy(multiplier):
def result(num):
return num * multiplier
return result
multiplyByThree = multiplyBy(3)
multiplyByThree(4)
------------
Output
------------
12
JavaScript。
function multiplyBy(multiplier) {
return function result(num) {
return num * multiplier
}
}
multiplyByThree = multiplyBy(3)
multiplyByThree(4)
------------
Output
------------
12
构建filter()、map()和reduce()。
让我们使用高阶函数(它们实际上是)建立一个简单版本的流行函数。
filter() aka filtering()
filtering 函数将有2个参数,一个array 和一个test 函数,它将返回一个新的数组,其中包含所有通过测试的元素。
Python。
def filtering(arr, test):
passed = []
for element in arr:
if (test(element)):
passed.append(element)
return passed
def isSuperNumber(num):
return num >= 10
filtering([1, 5, 11, 3, 22], isSuperNumber)
------------
Output
------------
[11, 22]
JavaScript。
function filtering(arr, test) {
const passed = []
for (let element of arr) {
if (test(element)) {
passed.push(element)
}
}
return passed
}
function isSuperNumber(num) {
return num >= 10
}
filtering([1, 5, 11, 3, 22], isSuperNumber)
------------
Output
------------
> (2) [11, 22]
可以看出,我们的filter() 函数非常容易编码,用于例如从一个数组😛中获取所有的超级数字。
map() 又名mapping()
函数mapping 将接受2个参数:一个array 和一个transform 函数,它将返回一个新的转换数组,其中每一项都是在原数组的每个元素上调用transform 函数的结果。
Python。
def mapping(arr, transform):
mapped = []
for element in arr:
mapped.append(transform(element))
return mapped
def addTwo(num):
return num+2
mapping([1, 2, 3], addTwo)
------------
Output
------------
[3, 4, 5]
JavaScript。
function mapping(arr, transform) {
const mapped = []
for (let element of arr) {
mapped.push(transform(element))
}
return mapped
}
function addTwo(num) {
return num + 2
}
mapping([1, 2, 3], addTwo)
------------
Output
------------
> (3) [3, 4, 5]
reduce() aka reducing()
函数reducing 将接受3个参数:一个reducer 函数,一个用于累加器的initial value ,以及一个array 。对于数组中的每一项,都会调用reduction函数,将累加器和当前数组元素传给它。返回值被分配给累加器。当它完成对列表中所有项的还原后,返回累积值。
Python。
def reducing(reducer, initial, arr):
acc = initial
for element in arr:
acc = reducer(acc, element)
return acc
def accum(acc, curr):
return acc + curr
reducing(accum, 0, [1, 2, 3])
------------
Output
------------
6
JavaScript。
function reducing(reducer, initial, arr) {
let acc = initial
for (element of arr) {
acc = reducer(acc, element)
}
return acc
}
function accum(acc, curr) {
return acc + curr
}
reducing(accum, 0, [1, 2, 3])
------------
Output
------------
6
结语
下次当你到了那个面试的时候,或者干脆你看到一个模式,一个函数要么被返回,要么被当作参数,你就知道我们在处理高阶函数。
今天我第一次介绍了一篇涵盖一种以上语言的文章,如果你觉得这是一个展示和比较它们的好方法,或者你认为这是一个糟糕的想法,请在评论中或通过twitter告诉我,我很想听到你的想法。