コードの書き方がどう変わってくるかなという視点で比較してみました。
for文とは
for文は繰り返し実行するための文です
for文(フォーぶん)はプログラミング言語において条件が真の間だけ与えられた文の実行を繰り返すというループを記述するための文である。 forループは、whileループと違って、ループに入る前の初期化(通常カウンタ変数の初期化を行なう)を含む点で異なる。
1 2 3 4 5 6 7 8 |
const numbers = [1, 2, 3, 4, 5]; // for let result1 = []; for (let i = 0; numbers.length > i; i++) { result1[i] = numbers[i] * 2; } console.log(result1); // -> [2, 4, 6, 8, 10] |
mapとは
mapとは与えられた関数を全ての要素に対して呼び出して、新しい配列を作るものです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map
1 2 3 4 5 6 7 |
const numbers = [1, 2, 3, 4, 5]; // map let result = numbers.map((x) => { return x * 2; }) console.log(result); // -> [2, 4, 6, 8, 10] |
numbersの配列データをmap関数を使って新しい配列resultを作りました。
map内は無名関数で、numbersの配列データが1つ1つこの無名関数で処理されて新しい配列の要素を生成します。
今回の関数は与えられた数値を2倍するというものです。
それぞれの違い
ここでそれぞれの書き方を比較してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const numbers = [1, 2, 3, 4, 5]; // for let result1 = []; for (let i = 0; numbers.length > i; i++) { result1[i] = numbers[i] * 2; } console.log(result1); // -> [2, 4, 6, 8, 10] // map let result2 = numbers.map((x) => { return x * 2; }) console.log(result2); // -> [2, 4, 6, 8, 10] |
for
- 処理結果を格納しているresult1に初期値として配列を代入している
- forは添字へのアクセスにiを使用している
- 関数化されていない
map
- 初期値の代入が不要
- 添字へのアクセスが不要
- 関数化されている
もう少し複雑な例
次に、配列以外の変数にも同様の(値を2倍にする)処理が必要になった場合、forループ内の処理(mapのcallback関数)を外出ししたくなると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// for (() => { let number = 6; let numbers = [1, 2, 3, 4, 5]; const mul = (a, b) => { return a * b } let result = mul(number, 2) let results = []; for (let i = 0; numbers.length > i; i++) { results[i] = mul(numbers[i], 2) } console.log(result) console.log(results); })(); // map (() => { let number = 6; let numbers = [1, 2, 3, 4, 5]; const mul = (a) => { return (b) => { return a * b; } } let result = mul(number)(2) let results = numbers.map(mul(2)) console.log(result) console.log(results); })(); |
掛け算を実行できるmul関数を作成してみました。mapの方のmul関数はカリー化しておりmap関数で直接使用できるようになっています。
更に複雑な例
受け取った値を100倍して1加算するという関数を作ってみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
// for (() => { let number = 6; let numbers = [1, 2, 3, 4, 5]; const mul = (a, b) => { return a * b } const add = (a, b) => { return a + b } // 元の値を100倍してから1加算する関数 const calc = (target) => { let tmp = mul(target, 100) tmp = add(tmp, 1) return tmp } let result = calc(number) let results = []; for (let i = 0; numbers.length > i; i++) { results[i] = calc(numbers[i]) } console.log(result) console.log(results); })(); // map (() => { let number = 6; let numbers = [1, 2, 3, 4, 5]; const compose = (f, g) => { return function (x) { return f(g(x)) } } const mul = (a) => { return (b) => { return a * b; } } const add = (a) => { return (b) => { return a + b; } } // 元の値を100倍してから1加算する関数を合成する const calc = compose(add(1), mul(100)) let result = calc(number) let results = numbers.map(calc) console.log(result) console.log(results); })(); |
mapの方は関数合成してみました。for文はiやtmpなどの手続き上必要になってくる変数がでてきますが、map(と関数合成)を使用している方はそういった無駄が見えてきません。