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])