👌

【JavaScript】繰り返し処理の学習記録

2024/09/18に公開

参考

プログラミング中級者になりたい人のためのクリーンコード入門
https://www.udemy.com/share/107mKo3@DI6OXMC-YLGUHBTV4GZzUZGMJAmLQ9bM4Pkzz1MSYJM8D_lkvhyw0mi5EE2GHmyC/

for文とwhile文

for文とwhile文では、for文の優先順位が高いです。
理由は、初期化式、条件式、変化式の処理がまとまっていて、読みやすいからです。

for文の場合

以下はJavaScriptでfor文を書くときの例です。

for (let i = 0; i < 10; i++) {
  // 初期化式; 条件式; 変化式
  // 何らかの処理
}

while文の場合

一方、while 文はループ制御(初期化式、条件式、変化式)が一箇所にまとまっていないため、色んな場所を見てループ制御を理解する必要があります。

//変数iの初期化
let i = 0;

//条件式
while (i < 10) {
  // 何らかの処理

  //変化式
  i++;
}

特定の条件でループを終了する場合には while 文が適しています。

// 乱数が 0.5 以上の時にループを継続
let loopCount = 0;
while (Math.random() > 0.5) {
  console.log(++loopCount);
}

for文とwhile文の使い分け

  • ループの回数を指定するとき → for 文を利用を利用した方が読みやすい
  • 特定の条件でループを抜けるとき → while 文を利用が読みやすい

forEach文

forEach文を使って、配列やオブジェクトをループさせることができます。
こちらが公式ドキュメントです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

forを使った場合

for文を使った場合は、次のような記述になります。

const fruits = ["apple", "tomato", "banana"];

for (let i = 0; i < fruits.length; i++) {
  // ループの終了条件やカウンタなどの設定が必要
  console.log(fruits[i]);
}

forEachを使った場合

forEachを使った場合は、次のような記述になります。

const fruits = ["apple", "tomato", "banana"];

fruits.forEach(function (fruit) {
  console.log(fruit);
});

どちらも同じ実行結果ですが forEach 文を使用することで、コールバック関数に実行したい処理を記述するだけで済みます。
無駄な記述を減らしミスを軽減したりコードの管理をしやすくすることができます。

map文

map は、コールバック関数を配列の各要素に対して呼び出し、その結果を格納した新しい配列を生成する高階関数です。
こちらが公式ドキュメントです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map

array.map(function (element, index, array) {
  // ...
});

コールバック関数は、以下の引数とともに呼び出されます。

  • 第一引数: 現在処理されている配列の要素
  • 第二引数: 現在処理されている配列のインデックス
  • 第三引数: 処理対象の配列

map文はfor文で書いた場合と比較して次のメリットがあります。

  • 空の配列を用意しなくても良い
  • カウンタ変数などを設定しなくても良い。

for文で書いた場合

const fruits = ["apple", "melon", "banana"];

let fruitsJuice = [];
for (let i = 0; i < fruits.length; i++) {
  fruitsJuice[i] = fruits[i] + "juice";
}

console.log(fruitsJuice);

//出力される値
// > ['applejuise', 'melonjuise', 'bananajuise']

こちらの例文では、fruitsという配列にapple,melon,bananaという要素が入っています。
fruitsJuiceという空の配列を宣言して、for文に必要なカウンタ変数を使いながらfruitsの配列を操作しています。
1つ1つの要素に対して、juiceという文字列を追加して、fruitsJuiceの配列に代入しています。

次に、map文で書いた場合の例文を確認します。

map文で書いた場合

const fruits = ["apple", "tomato", "banana"];
const fruitsJuice = fruits.map(function (data, index, array) {
  // 戻り値として加工する内容を記述する
  return data + "juice";
});

console.log(fruitsJuice);
// 出力される値
// > ['applejuice', 'tomatojuice', 'bananajuice']

// 新しい配列を新たに生成するため、元の配列には影響を与えません。
console.log(fruits);
// > ['apple', 'tomato', 'banana']

for文で宣言していた空の配列がなくなり、さらにfor文で設定していたカウンタ変数もなくなっています。
fruitsJuiceという配列は、配列のmapメソッドを呼んだ戻り値として用意してあります。
mapメソッドの中では、関数を渡してあり、その引数に配列の要素1つ1つを渡していきます。
return のところで、data + "juice"を返却しています。
結果として、fruitsJuiceの配列には、juiceの文字列が追加された新しい要素が入っています。

filter文

filter は、指定されたコールバック関数で個々の要素を判定し、条件に合致した要素だけを取り出した新しい配列を生成する高階関数です。
公式ドキュメントはこちらです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

filter の使い方

array.filter(function (element, index, array) {
  // ...
});

コールバック関数は、以下の引数とともに呼び出されます。

  • 第一引数: 現在処理されている配列の要素
  • 第二引数: 現在処理されている配列のインデックス
  • 第三引数: 処理対象の配列

for文を使った場合

const nations = [
  { name: "Japan", region: "Asia" },
  { name: "Italy", region: "Europe" },
  { name: "China", region: "Asia" },
  { name: "France", region: "Europe" },
];

const resultNations = [];

for (let i = 0; i < nations.length; i++) {
  if (nations[i].region === "Asia") {
    resultNations.push(nations[i]);
  }
}
console.log(resultNations);

// 出力される値
// > [{name: 'Japan', region: 'Asia'},{name: 'China', region: 'Asia'}]

こちらも同様に、ループの終了条件やカウンタなどの設定が必要です。
また for 文のなかで if 分で条件判定して、空の配列に格納する必要があります。
フィルターをかけるだけですが、コード量が増えて全体が複雑に見えてしまいます。

filter文を使った場合

const nations = [
  { name: "Japan", region: "Asia" },
  { name: "Italy", region: "Europe" },
  { name: "China", region: "Asia" },
  { name: "France", region: "Europe" },
];

const resultNations = nations.filter(function (nation) {
  return nation.region === "Asia";
});

console.log(resultNations);

// 出力される値
// > [{name: 'Japan', region: 'Asia'},{name: 'China', region: 'Asia'}]

filterを使っただけで空の配列を用意したり、カウンタ変数の設定をしたりしなくてもよくなりました。

まとめ

繰り返し処理でよく出てくるfor,while,foreach,map,filterについて違いを書きました。

Discussion