高阶 reduce() 函数
Higher-order reduce() function
我想抽象化传递到我的数组的 reduce()
函数中的函数,使该函数成为通用函数 'greatest of the Array reducer'。为此,我想在 reduce()
参数中传入不同的特定函数,以便能够指定比较标准。在我的示例中,这些是行
return players.reduce(topPlayerReducer, players[0], getThreePointerPercentage);
和
return players.reduce(topPlayerReducer, players[0], getReboundNumber);
其中 topPlayerReducer
是传递给 reduce()
的通用函数,它根据某些条件查找数组中的最大项。我的标准是第三个参数。我如何合并我的特定比较函数(getThreePointerPercentage
和 getReboundNumber
),以便保持这种抽象级别?现在,我收到 fn
不是 topPlayerReducer
中的函数的错误。我对此并不感到惊讶,因为我的其他功能不在范围内。我也试过
var reboundReducer = topPlayerReducer.bind(getReboundNumber);
return gameInfo.players.reduce(reboundReducer, players[0]);}
但我遇到了同样的错误。
我意识到我可以通过为 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
的实现,使其 returns 比较两个玩家的函数,而不是比较玩家本身:
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]);
或
return gameInfo.players.reduce(topPlayerReducer(getReboundNumber), gameInfo.players[0]);
通过这种方式,您可以在对 reduce
进行的每个不同调用中传递自定义函数,您只需先 'wrap it up' 在 topPlayerReducer
中。我认为这就是您试图通过 bind
.
实现的目标
仅供参考:我认为您在 bind
中寻找的是称为 部分应用程序 的东西,其中您采用具有多个参数的函数,提供一些但不是全部的参数,并取回一个需要剩余参数的函数。
你可以用 bind
来做到这一点,但你必须记住:
- 绑定需要一个额外的参数,该参数绑定到函数内的
this
,
- 您'pre-loading'的参数将从左侧开始填写。
因此,如果您进行了以下更改,那么您使用绑定的尝试将会奏效:
// 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
版本只是在这种情况下增加了混乱。 bind
在你有使用 this
的函数时很有用,但是你需要一种方法来改变它的值。
我想抽象化传递到我的数组的 reduce()
函数中的函数,使该函数成为通用函数 'greatest of the Array reducer'。为此,我想在 reduce()
参数中传入不同的特定函数,以便能够指定比较标准。在我的示例中,这些是行
return players.reduce(topPlayerReducer, players[0], getThreePointerPercentage);
和
return players.reduce(topPlayerReducer, players[0], getReboundNumber);
其中 topPlayerReducer
是传递给 reduce()
的通用函数,它根据某些条件查找数组中的最大项。我的标准是第三个参数。我如何合并我的特定比较函数(getThreePointerPercentage
和 getReboundNumber
),以便保持这种抽象级别?现在,我收到 fn
不是 topPlayerReducer
中的函数的错误。我对此并不感到惊讶,因为我的其他功能不在范围内。我也试过
var reboundReducer = topPlayerReducer.bind(getReboundNumber);
return gameInfo.players.reduce(reboundReducer, players[0]);}
但我遇到了同样的错误。
我意识到我可以通过为 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
的实现,使其 returns 比较两个玩家的函数,而不是比较玩家本身:
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]);
或
return gameInfo.players.reduce(topPlayerReducer(getReboundNumber), gameInfo.players[0]);
通过这种方式,您可以在对 reduce
进行的每个不同调用中传递自定义函数,您只需先 'wrap it up' 在 topPlayerReducer
中。我认为这就是您试图通过 bind
.
仅供参考:我认为您在 bind
中寻找的是称为 部分应用程序 的东西,其中您采用具有多个参数的函数,提供一些但不是全部的参数,并取回一个需要剩余参数的函数。
你可以用 bind
来做到这一点,但你必须记住:
- 绑定需要一个额外的参数,该参数绑定到函数内的
this
, - 您'pre-loading'的参数将从左侧开始填写。
因此,如果您进行了以下更改,那么您使用绑定的尝试将会奏效:
// 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
版本只是在这种情况下增加了混乱。 bind
在你有使用 this
的函数时很有用,但是你需要一种方法来改变它的值。