1
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?

初学者ワイ、ループ処理につまづいたので調べてみた。

Last updated at Posted at 2023-12-26

はじめに

こんにちは!堕罪オサムです。

私、for文とかのループ処理を書くのがめっちゃ苦手なんです……。だからなんだよと言われるとアレなんですけども。泣

あまりにfor文が分からなかったので、for文の中身を分解して理解を深めようと思います!

また後半はfor文以外のループ処理についても引用をして理解を深めました。

for文やループ処理が苦手だといった仲間がいらっしゃいましたらぜひ読んでみてほしいです。

よろしくお願いします!

for文とは

for文(for statement)とは、多くのプログラミング言語に用意されている構文の一つで、繰り返し(ループ)処理を記述するためのもの。決まった回数の繰り返しを記述するために用いられることが多い。

引用:IT用語辞典 for文 【for statement】 forループ / for loop から

for (初期化式; 条件式; 変化式){} // {}内に処理を書く

// よく見る形式はこれ
for (let i = 0; i < 9; i++){
  //以下実行する処理
}

めっちゃくちゃわかるように分解・説明

今回は初期値をx、条件式の値をyとして説明します。

var i = x;
初期値が入る・たいていの場合は0にする。

i < y;
何回ループするかの条件。例えばi<9だったらiが8になるまで処理が続く。

i++
上の例でいうとyが9の場合、9になったとき(i<9が正しくなくなったとき)に処理を止めるためにiを1づつ増やしている。

なぜiを使うのか

ループカウンタで変数iがよく使われている理由は、最も古い高級プログラミング言語のFORTRANの暗黙ルールが由来とされています。
この暗黙ルールでは、型の宣言をしていない変数名の先頭文字が'A'から'H'、'O'から'Z'の場合は実数型、それ以外のIからNは整数型となります。
ループに使う変数は整数型なので、古いFORTRANではループを作るときは変数名Iを使っていました。
(中略)
FORTRANより後に出てきたプログラミング言語のC言語、Javaでも慣習で、ループの変数にi、j、k、l、mを使うことが多いです。

引用:Javaを使ったプログラミング学習 ゆるゆるプログラミング から

for文以外のループ処理

JavaScriptでのループ処理は以下のような種類があります。

  • while文
  • do...while文
  • for...in 文
  • for...of 文
  • ラベルつき文
  • break 文
  • continue 文
  • forEach() <=別節で紹介

break文・continue文は以前投稿した「breakとreturnとcontinueの違いがよく分からんのでまとめてみたよ~!」でまとめたので今回は割愛させていただきます。

説明文は↑リンクから引用します。

while文

while文指定された条件がtrueに評価される限り文を実行します。
条件式がfalseとなる場合、ループ内の文は実行を停止し、ループに続く文に制御が渡されます。
ループ内の文が実行される前に条件がテストされます。
条件がtrueを返す場合、文は実行され、条件が再びテストされます。
条件がfalseを返す場合、実行は停止し、whileの次の文に制御が渡されます。
複数の文を実行するには、それらの文をグループ化するブロック文({ ... })を使用します。

let n = 0;
let x = 0;
while (n < 3) {  // このwhile ループは、n が 3 未満の場合繰り返されます。
  n++;
  x += n;  //各反復で、n がインクリメントされ、その値が x に加算されます。
}

【結果】

  • 1 回目の反復後 : n = 1, x = 1
  • 2 回目の反復後 : n = 2, x = 3
  • 3 回目の反復後 : n = 3, x = 6

do...while文

は条件式がチェックされる前に毎回一度実行されます。(複数の文を実行するには、ブロック文({ ... })を使って一つの文にします)。
条件式がtrueの場合、文が再び実行されます。
文の実行終了時に毎回条件がチェックされます。
条件がfalseの場合、実行は停止し、制御はdo...whileの次の文に渡ります。

//次の例では、do ループは少なくとも一度繰り返されます。
//そして i が 5 未満でなくなる直前まで繰り返されます。
let i = 0;
do {
  i += 1;           //文
  console.log(i);  //文
} while (i < 5);  //(条件式)

for...in 文

for...in文はオブジェクトにあるすべての列挙可能なプロパティに対し指定された変数を通して反復処理を行います。
それぞれの異なるプロパティに、JavaScriptは指定された文を実行します。for...in文は下記のようになります

//次の関数は引数としてオブジェクトと、そのオブジェクトの名前を表す文字列を取ります。
//それからすべてのオブジェクトのプロパティに対して反復し、プロパティ名とその値を表示する文字列を返します。
function dump_props(obj, obj_name) {
  let result = "";
  for (let i in obj) {  // (変数 in オブジェクト)
    result += obj_name + "." + i + " = " + obj[i] + "<br>";
  }
  result += "<hr>";
  return result;
}

Arrayの要素に対して反復処理を行う方法としてfor...in文を使用したくなるかもしれませんが、これは数値のインデックスに加えてユーザー定義プロパティの名前も返します。
そのため、配列に対しての反復処理には、数値のインデックスを使い従来のforループを使用するほうが良いです。
なぜなら、(カスタムプロパティやカスタムメソッドを追加するといった) Array オブジェクトの変更を行った場合、for...in文は配列要素に加えてユーザー定義プロパティに対しても反復処理するからです。

for...of 文

for...of文は、反復可能オブジェクト (en-US)(Array、Map、Set、arguments オブジェクトなどを含む)を反復処理するループを生成し、それぞれのプロパティの値に対して実行したい文をともなって作られた反復処理フックを呼び出します。

// 次の例では、`for...of`ループと`for...in`ループとの違いを示しています。
// for...in はプロパティ名に対し反復処理される一方、for...of はプロパティの値に対し反復処理します
const arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) { // for...in文の例
//配列「arr」の値が、変数に1つずつ代入されていく。
  console.log(i); // 変数i:"0", "1", "2", "foo" が出力される文
}

for (let i of arr) { // for...of文の例 「配列」の値を1つずつ「変数」へ代入する。
  console.log(i); // 変数i:3, 5, 7 が出力される文
}

注意しなければならないのは、for...of文は、イテラブル(反復可能である)・オブジェクトの場合のみ利用できるという点です。

JavaScriptにおいて、イテラブル(反復可能)なオブジェクトは、Symbol.iteratorと呼ばれる特別なメソッドを持つオブジェクトです。このメソッドは、オブジェクト自体が反復可能であるかどうかを示します。イテラブルなオブジェクトは、for...of ループなどで使用できます。

// イテラブルなオブジェクトの例
const iterableObject = {
  values: [1, 2, 3, 4],
  [Symbol.iterator]: function () { // Symbol.iteratorプロパティには、イテレータを生成するための関数が設定されている。
    let index = 0;
    const values = this.values;

    return {
      next: function () { // nextはイテレータが次の値を返すためのメソッド。
        return index < values.length
          ? { value: values[index++], done: false }
          : { done: true };  //三項演算子。
      }
    };
  }
};

// for...of ループでイテラブルなオブジェクトを使用
for (const value of iterableObject) {
  console.log(value);
  // 1
  // 2
  // 3
  // 4
}

[Symbol.iterator] プロパティ:
[Symbol.iterator] は、特殊なシンボルで、オブジェクトがイテラブルであることを示すために使用されます。このプロパティには、イテレータを生成するための関数が設定されています。

doneプロパティは、イテレーションが終了したかどうかを示すブール値。イテレーションが続く場合は false、終了した場合はtrueが設定されます。
indexvalues配列の長さよりも小さい場合はdone:falseのオブジェクトを返します。
それ以外の場合はdone: trueのオブジェクトを返します。

この例では、iterableObjectはSymbol.iteratorメソッドを持ち、そのメソッドはイテレータを返します。
イテレータはnextメソッドを持ち、各呼び出しで次の値と反復の終了を示すdoneプロパティを返します。このようなイテラブルなオブジェクトは、自分で定義することもできますが、JavaScriptには既にいくつかの組み込みのイテラブルなオブジェクトもあります。例えば、配列(Array)、文字列(String)、Map、Setなどが挙げられます。これらのオブジェクトは、デフォルトでSymbol.iteratorメソッドを持っており、for...ofループなどで直接反復できます。
引用:ChatGPT

forEach()について

公式ドキュメントではforEach()ループと反復処理ではなくArray.prototype.forEach()に記載があったため節を分けて記載します。

forEach()メソッド反復処理メソッドです。指定された関数callbackFnを配列に含まれる各要素に対して一度ずつ、昇順で呼び出します。

const array1 = ['a', 'b', 'c'];

array1.forEach((element) => console.log(element));

// Expected output: "a"
// Expected output: "b"
// Expected output: "c"

for ループから forEach への変換

const items = ["item1", "item2", "item3"];
const copyItems = [];

// before
for (let i = 0; i < items.length; i++) {
  copyItems.push(items[i]);
}

// after
items.forEach((item) => {
  copyItems.push(item);
});

最後に

今回はfor文を分解して理解を深めて、ほかのループ処理についても調査しました。
最後のほうは引用ばかりになってしまいましたが、個人的にはforループからforEach() への変換や、while文についても発見がありました。

ここまでご覧いただきありがとうございました!

1
0
3

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
1
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?