高阶reduce()函数

db2*_*791 3 javascript reduce higher-order-functions

我想抽象传递给我的数组reduce()函数的函数,使函数成为通用的"最大的Array reducer".为了实现这一点,我想在reduce()参数中传递不同的特定函数,以便能够指定比较的标准.在我的例子中,这些是线条

return players.reduce(topPlayerReducer, players[0], getThreePointerPercentage);

return players.reduce(topPlayerReducer, players[0], getReboundNumber);

topPlayerReducer传递给reduce()它的泛型函数在哪里根据某些条件查找数组中的最大项.我的标准是第三个论点.如何合并我的特定比较函数(getThreePointerPercentagegetReboundNumber),以便保持这种抽象级别?现在,我收到的错误fn不是函数topPlayerReducer.我对此并不感到惊讶,因为我的其他功能不在范围内.我也尝试过

var reboundReducer = topPlayerReducer.bind(getReboundNumber);

return gameInfo.players.reduce(reboundReducer, players[0]);}
Run Code Online (Sandbox Code Playgroud)

但我得到了同样的错误.

我意识到我可以通过制作两个不同的功能来实现结果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);
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*ter 5

我会这样做:

改变实现topPlayerReducer,使其返回一个比较两个玩家的函数,而不是比较玩家本身:

function topPlayerReducer(fn){
    return function(topPlayer, currentPlayer) {
        if (fn(currentPlayer) > fn(topPlayer)){
            return currentPlayer;
        } else {
            return topPlayer;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样打电话reduce:

return pointGuards.reduce(topPlayerReducer(getThreePointerPercentage), pointGuards[0]);
Run Code Online (Sandbox Code Playgroud)

要么

return gameInfo.players.reduce(topPlayerReducer(getReboundNumber), gameInfo.players[0]);
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以使用您所做的每个不同的调用传递自定义函数reduce,您只需topPlayerReducer先将其"包装"即可.我认为这是你想要实现的目标bind.


仅供参考:我认为您所寻找的bind部分应用程序,您可以使用多个参数来提供函数,提供一些但不是所有参数,并返回一个期望剩余参数的函数.你可以这样做bind,但你必须记住:

  1. 该绑定需要一个额外的参数,该参数绑定this在函数内,
  2. 您正在"预加载"的参数将从左侧填写.

因此,如果您进行了这些更改,那么您尝试使用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])
Run Code Online (Sandbox Code Playgroud)

对于我的钱,bind版本只是在这种情况下增加了混乱.但是,bind当你有使用的函数时,它可能很有用this,你需要一种方法来改变它的值.