2016-09-19 3 views
2

필자는 배열 'reduce()에 전달 된 함수를 추상화하여 함수를 일반적인'Array reducer 중 가장 큰 것 '으로 만들기 위해 함수를 추상화하려고합니다. 이를 달성하기 위해, 나는 비교 기준을 지정할 수 있도록 reduce() 매개 변수의 다른 특정 기능을 전달하려고합니다. 내 예에서, 이러한 라인Higher-order reduce() function

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

topPlayerReducer 몇 가지 기준에 따라 배열에서 가장 큰 항목을 발견 reduce()에 전달하는 일반 기능입니다

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

입니다. 내 기준은 세 번째 주장입니다. 이 비교 수준을 유지하기 위해 특정 비교 함수 ( getThreePointerPercentagegetReboundNumber)를 통합하려면 어떻게합니까? 현재 fntopPlayerReducer의 기능이 아닙니다. 내 다른 기능이 범위 내에 있지 않기 때문에 나는 이것에 놀라지 않는다. 또한

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); 
} 

답변

5

그래서처럼 할 것 :

변경 topPlayerReducer의 구현을 오히려 선수 자체를 비교하는 것보다, 두 선수를 비교하는 함수를 반환하도록 : 그럼 당신을

function topPlayerReducer(fn){ 
    return function(topPlayer, currentPlayer) { 
     if (fn(currentPlayer) > fn(topPlayer)){ 
      return currentPlayer; 
     } else { 
      return topPlayer; 
     } 
    } 
} 

을 와 같이 전화 할 수 있습니다.

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

또는

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

당신이 reduce로 만들어 각기 다른 호출을 사용자 정의 함수에 전달할 수있는이 방법, 당신은 단지 topPlayerReducer 먼저 '을 마무리'. 나는 이것이 당신이 bind으로 달성하려고 시도한 것이라고 생각합니다.


는 참고 : 나는 당신이 bind에서 찾고 있던 무언가 일부 응용 프로그램이 여러 인수 기능을,라는 것을 생각 인수의 전체가 아닌 일부를 공급하고, 다시 함수를 얻을 수있는 나머지 주장을 기대한다. 당신은 bind이 작업을 수행 할 수 있습니다,하지만 당신은 기억해야한다 : 당신이 인수가 '프리로드'채울 것을 바인딩은 함수 내 this에 바인딩 추가 인수를

  1. ,
  2. 을 에서 왼쪽으로.이러한 변경을했다 더라면

그래서 바인드를 사용하도록 시도 일 것이다 :

// 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 버전은이 상황에서 혼란을 추가합니다. bindthis을 사용하는 함수가있을 때 유용 할 수 있으며 값을 변경하는 방법이 필요합니다.

+0

이렇게했습니다. 그것이 작동하는 방법을 믿는 것은 조금 어렵지만 나는 그것을 얻었다고 생각합니다. – db2791

+0

차가움. 기본적으로 새 구현에서는'topPlayerReducer'를 호출 할 때마다 두 명의 플레이어를 필요로하고 조건을 만족하는 새로운 함수를 반환합니다. 이 방법으로 작성한 함수는 직접 정의한 함수와 동일하므로'reduce'와 모든 좋은 것을 전달할 수 있습니다. 좀 더 주위를 돌아보고 싶다면,'topPlayerReducer'를 조금만 노려보십시오 : 커맨드 라인/console에서'var foo = topPlayerReducer (someFunc)'를 호출하십시오. 그러면'foo '가 무엇인지 알 수 있고, 몇 가지 인자로 호출 할 수 있습니다. – Peter