Javascript 高阶reduce()函数
我想抽象传递到数组中的函数“Javascript 高阶reduce()函数,javascript,reduce,higher-order-functions,Javascript,Reduce,Higher Order Functions,我想抽象传递到数组中的函数“reduce()functions”,使该函数成为通用的“最大的数组reducer”。为了实现这一点,我想在reduce()参数中传入不同的特定函数,以便能够指定比较标准。在我的例子中,这些是 return players.reduce(topPlayerReducer,players[0],GetThreePercentage) 及 return players.reduce(topPlayerReducer,players[0],getNumber) 其中,top
reduce()
functions”,使该函数成为通用的“最大的数组reducer”。为了实现这一点,我想在reduce()
参数中传入不同的特定函数,以便能够指定比较标准。在我的例子中,这些是
return players.reduce(topPlayerReducer,players[0],GetThreePercentage)代码>
及
return players.reduce(topPlayerReducer,players[0],getNumber)代码>
其中,topPlayerReducer
是传递给reduce()
的通用函数,它根据某些条件查找数组中最大的项。我的标准是第三个参数。我如何合并我的特定比较函数(getthreepercentage
和getrecombnumber
)以保持这种抽象级别?现在,我得到一个错误,fn
不是topPlayerReducer
中的函数。我对此并不感到惊讶,因为我的其他函数不在范围内。我也试过这样做
var recombreducer=topPlayerReducer.bind(getrecombnumber)代码>
但我也犯了同样的错误
我意识到我可以通过为reduce()
生成两个不同的函数来实现一个结果,但这并不能满足我的要求。我想知道是否有不同的方法
function getGuardWithMostThreePointers(gameInfo){
return players.reduce(topPlayerReducer, players[0], getThreePointerPercentage);
}
function getPlayerWithMostRebounds(gameInfo){
return players.reduce(topPlayerReducer, players[0], getReboundNumber);
}
function topPlayerReducer(topPlayer, currentPlayer, fn){
if (fn(currentPlayer) > fn(topPlayer)){
return currentPlayer;
} else {
return topRebounder;
}
}
function getReboundNumber(player){
return parseInt(player.rebounds_offensive) + parseInt(player.rebounds_defensive);
}
function getThreePointerPercentage(player){
return parseInt(player.three_pointers_made) / parseInt(player.three_pointers_attempted);
}
我想这样做:
更改topPlayerReducer
的实现,使其返回一个比较两个播放器的函数,而不是比较播放器本身:
function topPlayerReducer(fn){
return function(topPlayer, currentPlayer) {
if (fn(currentPlayer) > fn(topPlayer)){
return currentPlayer;
} else {
return topPlayer;
}
}
}
然后您可以像这样调用reduce
:
return pointGuards.reduce(topPlayerReducer(getThreePointerPercentage), pointGuards[0]);
或
通过这种方式,您可以在每次调用reduce
时传入一个自定义函数,您只需先在TopLayerReducer
中“包装”它即可。我认为这就是您试图通过bind
实现的目标
仅供参考:我认为您在bind
中寻找的是一种称为部分应用程序的东西,在该应用程序中,您获取一个具有多个参数的函数,提供一些但不是全部参数,然后返回一个需要剩余参数的函数。
您可以使用bind
执行此操作,但必须记住:
该绑定接受一个额外的参数,该参数绑定到函数中的this
您正在“预加载”的参数将从左侧填充
因此,如果您进行了以下更改,那么您尝试使用bind的操作将成功:
// Make fn the leftmost parameter
function topPlayerReducer(fn, topPlayer, currentPlayer){
if (fn(currentPlayer) > fn(topPlayer)){
return currentPlayer;
} else {
return topRebounder;
}
}
// Add an extra 'null' argument to be bound to the `this` variable
return players.reduce(topPlayerReducer.bind(null, getReboundNumber), players[0])
就我而言,bind
版本只会在这种情况下增加混乱<代码>绑定
在您有使用此
的函数时非常有用,但是,您需要一种方法来更改其值。这很有效!很难相信它是怎么工作的,但我想我明白了。酷。基本上,在新的实现中,每次调用topPlayerReducer
时,它都会返回一个全新的函数,该函数包含两个参与者,并返回满足条件的一个参与者。以这种方式创建的函数与直接定义的函数完全相同,因此可以将其传递到reduce
以及所有这些好的东西中。如果您想进一步了解它,请尝试稍微摆弄一下topPlayerReducer
:在命令行/控制台上调用var foo=topPlayerReducer(someFunc)
。然后你可以看到什么是foo
,试着用一些参数来调用它,等等。
return gameInfo.players.reduce(topPlayerReducer(getReboundNumber), gameInfo.players[0]);
// Make fn the leftmost parameter
function topPlayerReducer(fn, topPlayer, currentPlayer){
if (fn(currentPlayer) > fn(topPlayer)){
return currentPlayer;
} else {
return topRebounder;
}
}
// Add an extra 'null' argument to be bound to the `this` variable
return players.reduce(topPlayerReducer.bind(null, getReboundNumber), players[0])