2017-08-29 9 views
15

私は、2つの数値を乗算することはできますが、問題を抱えている関数に値をマップしようとしています(これが意味をなさない場合は、以下の例を参照してください)。array.map()にパラメータを渡す方法は?

私は数字の配列を持っています。私はこの配列の値を倍精度/三重/四倍にしたいと思います。私はこれを行う関数を作成しており、double()triple()map()に入力しています。

var arr = [1, 2, 3, 4, 5]; 

function double(num) { 
    return num * 2; 
} 

function triple(num) { 
    return num * 3; 
} 

console.log(arr.map(double)); 
console.log(arr.map(triple)); 

このソリューションは、値を5または10で乗算したい場合にはスケーラビリティがありません。私は何を乗算するかというパラメータを取るより抽象的な関数が必要です。私はこれを行う方法について混乱しています。私の試みはこれまでのところです:

var arr = [1, 2, 3, 4, 5]; 

function multiply(num, multiplyBy) { 
    return num * multiplyBy; 
} 

console.log(arr.map(multiplyBy(4)); // Uncaught TypeError: NaN is not a function 

がどのように私はmultiply()multiplyByパラメータ渡すでしょうか?

答えて

16

工場と呼ばれることができます。効果的には、ニーズに合わせた別の関数を返す関数を作成します。この場合、匿名のものです。

var arr = [1, 2, 3, 4, 5]; 

function multiplyBy(scale) { 
    return function(num){ 
     return num * scale; 
    } 
} 

console.log(arr.map(multiplyBy(4))); 

これは、返される匿名関数の範囲が工場の範囲内にあるためです。したがって、新しい関数を生成するたびに、その生成のために与えられた値scaleが保持されます。

編集:@Bergiの答えの最後の部分は私のものと同じです。このコンセプトは、明らかにカレーと呼ばれています。ありがとう@ベルギー! Bergiが指摘したように、Factoryパターンはオブジェクトの生成に適用されることが多くなりましたが、その時点で私が考えることができるのは唯一のものでした.JavaScriptのsortはオブジェクトのような関数を扱います。この特定のケースでは、それらは事実上類似している。

+3

オブジェクトを返す関数に対してのみ、「ファクトリ」という用語を使用します。 – Bergi

+0

私は自分の答えをより読みやすくしました。私は奇妙な字下げを使用して、ES6の矢印機能のワンライナーへの変換をより明白にしました。 – Bergi

+1

この答えは '.bind'を使うよりも理解しやすいです – Denny

10

Function.prototype.bindを使用すると、バインドされた引数を使用して新しい関数を作成できます。例

var arr = [1, 2, 3, 4, 5]; 
 

 
function multiplyBy(multiplyBy, num) { 
 
    // note the "num" argument must come last if it is to represent the argument from "map" 
 
    return num * multiplyBy; 
 
} 
 

 
console.log(arr.map(multiplyBy.bind(null, 4))); // null is for the "this" argument

14

のためにあなたはpartial applicationを探しています。それは、例えばbindで行うことができます(またはin Underscoreのような、機能的なライブラリが付属してヘルパー関数の数):

arr.map(multiplyBy.bind(null, 4)) 

は、しかし、単純な矢印の機能が容易になるだろう:

arr.map(x => multiplyBy(4, x)) 

しかし、あなたもしあなたが multiplyBy関数で乗数をとり、新しい関数を返すなら、無料で部分的なアプリケーションを得ることができます:

function multiplyBy(multiplier) { 
    return function(num) { 
    return num * multiplier; 
    }; 
} 
// ES6 arrow functions: 
const multiplyBy = multiplier => num => num * multiplier; 

arr.map(multiplyBy(4)); 
関連する問題