3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScriptにおける繰り返し構文、反復処理まとめ

Posted at

はじめに

自分自身が繰り返し構文、反復処理メソッドをなんとなくで使っている気がして、一度一通り勉強しなおそうということで記事にしました。

繰り返し構文、反復処理メソッド一覧

  • 繰り返し構文
    • for
    • for...in
    • for...of
    • do while
    • while
  • 反復処理メソッド
    • forEach
    • map
    • filter
    • reduce

よく使われる、よく聞く繰り返し処理を列挙しました。

for

const array = [1, 2, 3];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}
// => 1
// => 2
// => 3

スタンダードな繰り返し文。

上記のコードでは、変数iが実行回数を保持し、for文の中の処理が終わったら変数iに 1 ずつ足して実行回数をカウントする。変数iが配列の長さ分より数値が大きくなったら処理終了。

繰り返し条件の変更もしやすく汎用性が高い半面、パッと見で何の処理を行う繰り返し文なのかが分かりづらい特徴がある。

for...of

const array = ["foo", "bar", "baz"];
for (const i of array) {
  console.log(i);
}
// => foo
// => bar
// => baz

基本は配列に有効な繰り返し文。

オブジェクトのプロパティーのキーだけ出力したい、プロパティーの値だけ出力したいといった場合には、下記のようにオブジェクトを配列に変換する処理をはさむ必要がある。

例.プロパティーのキーを出力

const array = { a: 1, b: 2, c: 3 };
const newArray = Object.keys(array); // newArray => ["a", "b", "c"]
for (const key of newArray) {
  console.log(key);
}
// => a
// => b
// => c

例.値を出力

const array = { a: 1, b: 2, c: 3 };
const newArray = Object.values(array); // newArray => ["1", "2", "3"]
for (const value of newArray) {
  console.log(value);
}
// => 1
// => 2
// => 3

例.プロパティーのキーと値をセットにして出力

const array = { a: 1, b: 2, c: 3 };
const newArray = Object.entries(array); //newArray => [["a", 1], ["b", 2], ["c", 3]]
for (const entry of newArray) {
  console.log(entry);
}
// => ["a", 1]
// => ["b", 2]
// => ["c", 3]

for...in

オブジェクト・配列に対して使える繰り返し文。

for文と同じように処理条件内で変数を指定して、それをプロパティーのキーにしてプロパティーの値を出力する場合に使いやすい。

実行環境などによって必ずしも順序通りの出力に関して保証されないため、順序を気にせず列挙する場合に推奨。
※順序通りの出力を担保してほしい場合はfor文が推奨されている。

const array = { a: 1, b: 2, c: 3 };
for (const i in array) {
  console.log(`${i}:${array[i]}`);
}
// => a: 1
// => b: 2
// => c: 3
const array = ["foo", "bar", "baz"];
for (const i in array) {
  console.log(i);
}
// => 0
// => 1
// => 2

for...in と for...of の違い

処理対象が配列の場合、for...inプロパティーのキーに対して繰り返し処理を行うが、for...ofプロパティーの値に対して処理を行うため適材適所。

処理対象がオブジェクトの場合、for...inは出力順序に確実性は保証されないがプロパティーのキーもプロパティーの値もアクセスしやすくシンプルで使いやすい。

for...ofは基本オブジェクトに対して使用できないためプロパティーのキーのみもしくはプロパティーの値のみ、もしくはプロパティーのキーと値をセットにした配列のそれぞれを配列に変換してから処理を行う必要がある。

forEach

繰り返し構文ではないが、配列に対して有効な反復処理メソッド。

配列の値を順繰りコールバック関数が一つ一つ処理する、シンプルで使いやすいメソッド。

const array = ["foo", "bar", "baz"];
array.forEach((v) => {
  console.log(v);
});

forEach と for...of の違い

forEachではbreakcontinueが使えないため、returnなどで中断・スキップ処理を別の書き方をする必要があり、breakcontinueと違って一目で中断なのかスキップなのかが分かりづらい。

for...ofでインデックスを取得するにはObject.entriesで変換する必要があるが、forEachでは第二引数でindexを指定することができるのでインデックスを扱いやすい。
基本的には扱いやすいforEachを使うのがよさそう。

const array = [1, 2, 3];
for (const [index, v] of Object.entries(array)) {
  console.log(`index: ${index}, value: ${v}`);
}
// => index: 0, value: 1
// => index: 1, value: 2
// => index: 2, value: 3

for...of で特定の巡回をスキップする

const array = [1, 2, 3, 4, 5];
for (const [index, v] of Object.entries(array)) {
  if (index === "3") {
    continue;
  }
  console.log(`index: ${index}, value: ${v}`);
}
// => index: 0, value: 1
// => index: 1, value: 2
// => index: 2, value: 3
// => index: 4, value: 5

forEach で特定の巡回をスキップする

const array = [1, 2, 3, 4, 5];
array.forEach((v, index) => {
  if (index === 2) {
    return;
  }
  console.log(v);
});
// => 1
// => 2
// => 4
// => 5

forEachメソッドは第二引数にindexを指定することができ、上記では 3 回目でreturnを指定することでスキップしている。

do...while

指定した条件に対してfalseになるまで実行を続ける繰り返し構文。

条件は処理を行った後に判定されるため、1 巡目でfalseとなる条件でも 1 回実行されてからループを終了する。

let count = 0;

do {
  count++;
  console.log(count);
} while (count < 5);
// => 1
// => 2
// => 3
// => 4
// => 5
let count = 10;

do {
  count++;
  console.log(count);
} while (count < 5);
// => 11 初期値で条件を満たしていても1回実行される

while

do...whileと処理は似ているが、条件の判定が行われてから処理が走る。

let count = 0;

while (count < 5) {
  count++;
  console.log(count);
}
// => 1
// => 2
// => 3
// => 4
// => 5
let count = 10;

while (count < 5) {
  count++;
  console.log(count);
}
// 条件がすでにfalseなためログに出力されない

while と for の違い

どちらも似た繰り返し構文だが、for繰り返しの回数が決まっている場合、while繰り返し回数が決まっておらず条件がfalseにならない限り処理を続けたい場合で使い分けるのが慣例的。

map

繰り返し構文ではなく反復処理メソッドで、配列の要素一つ一つを順番にコールバック関数の処理を行い、新たな配列を生成する。

const array = [1, 2, 3, 4, 5];
const mapArray = array.map((v) => v * 2);
console.log(mapArray);
// => [2, 4, 6, 8, 10]

filter

こちらも繰り返し構文ではないが反復処理メソッドで、コールバック関数がtrueを返す要素だけを抽出して新たな配列を生成する。

const array = [1, 2, 3];
const newArray = array.filter((v) => v % 2 === 1);
console.log(newArray);
// => [1, 3]

reduce

コールバック関数で初期値に対して順番に要素を足し合わせて(積み重ねて)、配列から配列以外の累積値を生成する反復処理メソッド。

const array = [1, 2, 3];
const newArray = array.reduce((accu, curr) => accu + curr);
console.log(newArray);
// => 6 初期値であるaccuには0が入り、0 + 1 + 2 + 3 = 6となる

オブジェクトに対する forEach、map、filter、reduce

上記の反復処理メソッドは基本的に配列に対する処理を得意としている。

オブジェクトに対して使用するためにはObject.valuesObject.entriesなどを使用して配列に変換する前段階が必要。

まとめ

構文 主な対象 使用場面
for なんでも OK 繰り返し回数が決まっている処理
for...in 配列・オブジェクト 配列ならばキーに対して処理を行いたい場合に
オブジェクトならば出力順序の正確さを求めない場合
for...of 配列 プロパティーの値に対して処理を行いたい場合
while なんでも OK 条件がfalseにならない限り繰り返したい処理
do while なんでも OK 条件がfalseにならない限り繰り返したい処理
かつ 1 回は処理を行いたい場合
forEach 配列 配列からコールバック関数で汎用的な処理をしたい場合)
map 配列 配列からコールバック関数による処理で新たな配列を生成したい場合・
filter 配列 配列からコールバック関数による処理でtrueを返す要素を抽出した新たな配列を生成したい場合・
reduce 配列 配列からコールバック関数による処理で配列から配列以外の要素の累積値を生成したい場合・
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?