-
-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(loop): for文とforEach #80
Changes from 4 commits
7265e6f
0d378ea
c955e65
df05e3f
330e642
3a947e4
0cc2706
33a78b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
--- | ||
author: azu | ||
--- | ||
|
||
# ループと反復処理 | ||
|
||
|
||
プログラミングにおいて、同じ処理を繰り返すために同じコードを書くことはありません。 | ||
ループや再帰呼び出し、イテレータなどを使い反復処理は抽象化されます。 | ||
ここでは、もっとも基本的な反復処理となるループについてを学んでいきます。 | ||
|
||
## for文 | ||
|
||
for文はもっとも基本となるループ処理です。 | ||
JavaScriptのfor文はC言語やJavaと同様の構文になります。 | ||
|
||
```js | ||
for (初期化式; 条件式; 増分式) | ||
実行する文; | ||
``` | ||
|
||
for文の実行フローは次のようになります。 | ||
|
||
1. `初期化式` で変数の宣言 | ||
2. `条件式` の評価結果が`true`なら処理を続け、`false`なら終了 | ||
3. `実行する文` を実行 | ||
- 複数行である場合は、`{`と`}`のブロック文にする必要があります | ||
4. `増分式` で変数を更新 | ||
5. ステップ2へ戻り繰り返す | ||
|
||
次のコードでは、for文を使い1から10の合計値を計算しています。 | ||
|
||
```js | ||
var total = 0; // 初期値は0 | ||
for (var i = 0; i < 10; i++) { | ||
total += i + 1; // 1...10 | ||
} | ||
console.log(total); // => 55 | ||
``` | ||
|
||
このコードは1から10の合計を電卓で計算すればいいので、普通は必要ありませんね。 | ||
実際に扱うなら、数値の入った配列を受け取り、その合計を計算して返すという関数を実装することになります。 | ||
|
||
次のコードでは、任意の数値が入った配列を受け取り、その合計値を返す `sum` 関数を実装しています。 | ||
関数とブロック文それぞれのスコープがあるので、`var`を`let`に書き換えると間違って同じ変数名を再定義できなくなるのでより安全です。 | ||
<!-- スコープの説明をしてない --> | ||
|
||
[import, sum-for-example.js](./src/sum-for-example.js) | ||
|
||
一方、反復処理の多くは、配列に入れた値を処理する方法と言い換えることができます。 | ||
そのため、JavaScriptの配列である`Array`オブジェクトには反復処理をするためのメソッドが備わっています。 | ||
|
||
## Array.prototype.forEach | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for文とforEachのみにして、reduceは欄外に移した |
||
|
||
`Array`オブジェクトは、`map`、`reduce`などの反復処理のためのメソッドが用意されています。 | ||
`array.forEach(コールバック関数)`もそのひとつでfor文に近い反復処理をします。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
どれかの表記にまとめたい感じがする。 |
||
|
||
`forEach`メソッドは次のように書くことができます。 | ||
|
||
```js | ||
const array = [1, 2, 3, 4, 5]; | ||
array.forEach((currentValue, index, array) => { | ||
// 処理する文 | ||
}); | ||
``` | ||
|
||
JavaScriptでは、関数はファーストクラスであるため、その場で作った匿名関数(名前のない関数)を引数として渡すことができます。 | ||
|
||
引数として渡される関数のことを**コールバック関数**と呼びます。 | ||
また、`forEach`メソッドのようなコールバック関数を引数として受け取る関数やメソッドのことを**高階関数**と呼びます。 | ||
|
||
`array.forEach(コールバック関数)`のコールバック関数には、配列の先頭から順番に要素が渡されて実行されます。 | ||
つまり、コールバック関数の`currentValue`には1, 2, 3 …という値が順番に渡されて実行されます。 | ||
|
||
```js | ||
[1, 2, 3, 4, 5].forEach(currentValue => { | ||
console.log(num); | ||
}); | ||
// 1 | ||
// 2 | ||
// 3 | ||
// 4 | ||
// 5 | ||
// と順番に出力される | ||
``` | ||
|
||
先ほどのfor文で合計値を計算する`sum`関数を`forEach`メソッドで書いてみます。 | ||
|
||
[import, sum-forEach-example.js](./src/sum-forEach-example.js) | ||
|
||
`forEach`は`条件式`がなく、配列のすべての要素を走査するため、for文よりもシンプルな処理です。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ここから、実質的な違いである continueとbreakについて書いていく感じになるかな? |
||
|
||
|
||
### [コラム] `let`ではなく`const`で処理する | ||
|
||
先ほどのfor文や`forEach`メソッドでは`let`を`const`に変更することはできませでした。 | ||
なぜなら、for文は一度定義した変数に値の代入を繰り返し行う処理といえるからです。 | ||
`const` は再代入できない変数を宣言するキーワードであるためfor文とは相性がよくありません。 | ||
|
||
`let`ではなく`const`を使うためには、一度定義した変数に値を代入しつつ反復処理するのではなく、 | ||
反復処理処理からひとつの新しい値を返す方法が必要になります。 | ||
|
||
反復処理から新しい値を作るArrayメソッドとして`Array.prototype.reduce`があります。 | ||
`array.reduce(コールバック関数, 初期値)`は配列から新しい値を作り返すメソッドです。 | ||
|
||
さきほどの例である、配列から合計値を返すものを`reduce`メソッドを使い実装してみましょう。 | ||
|
||
`reduce`メソッドは2つづつの要素を取り出し(左から右へ)、その値を`コールバック関数`を適用し、 | ||
`次の値`として1つの値を返します。 | ||
最終的な、`reduce`メソッドの返り値は、コールバック関数が最後に`return`した値となります。 | ||
|
||
```js | ||
arrayObj.reduce((前回の値, 現在の値) => { | ||
return 次の値; | ||
}, 初期値); | ||
``` | ||
|
||
先ほどの配列の全要素の合計値を計算するものは`reduce`メソッドでは、次のように書くことができます。 | ||
`初期値`に`0`を指定し、`前回の値`と`現在の値`を足していくことで合計を計算できます。 | ||
`初期値`を指定していた場合は、最初の`前回の値`に初期値が、配列の先頭の値が`現在の値`となった常体で開始されます。 | ||
|
||
[import, sum-reduce-example.js](./src/sum-reduce-example.js) | ||
|
||
`reduce`メソッドを使った例では、そもそも変数宣言をしていないことが分かります。 | ||
`reduce`メソッドでは常に新しい値を返すことで、1つの変数の値を更新していく必要がなくなります。 | ||
これは`const`と同じく、一度作った変数の値を変更しないため、意図しない変数の更新を避けることにつながります。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
function sum(numbers) { | ||
let total = 0; | ||
for (let i = 0; i < numbers.length; i++) { | ||
total += numbers[i]; | ||
} | ||
return total; | ||
} | ||
|
||
sum([1, 2, 3, 4, 5]); // => 15 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
function sum(numbers) { | ||
let total = 0; | ||
numbers.forEach(num => { | ||
total += num; | ||
}); | ||
return total; | ||
} | ||
|
||
sum([1, 2, 3, 4, 5]); // => 15 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
function sum(numbers) { | ||
return numbers.reduce((total, num) => { | ||
return total + num; | ||
}, 0); // 初期値が0 | ||
} | ||
|
||
sum([1, 2, 3, 4, 5]); // => 15 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
一方
がどこにもかかってないので消す