Javascriptのループ文と反復処理を✅

友達から「顧客情報をハッシュ化させるコードを教えて」と言われて華麗にVBAでハッシュ化させるコードを書いて渡して感謝されて喜んでいる23期酒ケジュール作成中です。#検索する力が身についた

function SHA_256(input) {
  var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input, Utilities.Charset.UTF_8);
  var txtHash = '';
  for (i = 0; i < rawHash.length; i++) {
    var hashVal = rawHash[i];
    if (hashVal < 0) {
      hashVal += 256;
    }
    if (hashVal.toString(16).length == 1) {
      txtHash += '0';
    }
    txtHash += hashVal.toString(16);
  }
  return txtHash;
}

さて、今回はjavascriptのループ文と反復処理を学習していきたいと思います。

 

ループ文

  • while
  • do-while文
  • for文
  • 配列のforEachメソッド
  • break文
  • continue文
    • 配列のfilterメソッド
  • for...in文
  • for...of文

while文とfor文の違い

ざっくり2つの違いは以下の通り。

  • 繰り返し回数が決まっている場合はfor文
  • 繰り返し回数が決まっていない場合はwhile文

while

while文は条件式trueである限り反復処理を行い続ける。

while (条件式) {
    実行する文;
}

条件式がfalseになるまで実行する文を繰り返し処理する。

もしfalseにならない処理を実行してしまったら無限ループに陥ってしまうため、whileを使われる場面は限られている。

let x = 0;
console.log(`ループ開始前のxの値: ${x}`);
while (x < 10) {
    console.log(x);
    x += 1;
}
console.log(`ループ終了後のxの値: ${x}`);
ループ開始前のxの値: 0
0
1
2
3
4
5
6
7
8
9
ループ終了後のxの値: 10

do-while文

while文が後置修飾になった。必ず最初に実行する文が処理される点がwhile文とは違う点。

do {
    実行する文;
} while (条件式);

for文

for文は繰り返す範囲を指定した反復処理を書くことができる。

for (初期化式; 条件式; 増分式) {
    実行する文;
}

関数に繰り返し処理を記述することができる。

function sum(numbers) {
    let total = 0;
    for (let i = 0; i < numbers.length; i++) {
        total += numbers[i];
    }
    return total;
}

console.log(sum([1, 2, 3, 4, 5])); // => 15

配列のforEachメソッド

for文と同じように使うことができる。次のように使うことができる。

const array = [1, 2, 3];
array.forEach(currentValue => {
    // 配列の要素ごとに呼び出される処理
});

ここで使われているcurrentValueはコールバック関数といい、仮引数として使うことができる。

const array = [2, 3, 4];
array.forEach(currentValue => {
currentValue += 1
  console.log(currentValue)
});
# 3, 4, 5

for文同様、functionとして一まとまりに定義することもできる。

function years_ago (numbers) {
    let age = 21;
    numbers.forEach(num => {
        age -= num;
    });
    return age;
}

years_ago([1, 2, 3, 4, 5]);
#6

break

途中で処理を中断することができる。whileやfor文と組み合わせて、「ある条件を満たしたら処理を終了させる」という式を作成することが多い。

例えば配列に偶数があるかどうか調べたい時は、配列内のオブジェクトの数だけ繰り返し処理をする式を書く。

const numbers = [1, 5, 15,6];
# 偶数があるかどうか
let isEvenIncluded = false;
for (let i = 0; i < numbers.length; i++) {
    const num = numbers[i];
    if (num % 2 === 0) {
        isEvenIncluded = true;
        break;
    }
}

関数外の式をisEvenIncludedに呼び出して使うこともできる。isEvenとisEvenIncludedという風に、二つの関数へ切り出すことで可読性を高めている。

function isEven(num) {
    return num % 2 === 0;
}
function isEvenIncluded(numbers) {
    for (let i = 0; i < numbers.length; i++) {
        const num = numbers[i];
        if (isEven(num)) {
            return true;
        }
    }
    return false;

continue文

現在の反復処理を終了して、次の反復処理を行う。 while、do-while、forの中で使うことができる。

たとえば、while文の処理中でcontinue文が実行されると、現在の反復処理はその時点で終了され、 次の反復処理で条件式を評価するところからループが再開される。

while (条件式) {
    // 実行される処理
    continue; // `条件式` へ
    // これ以降の行は実行されません
}

配列の中からhighballという文字列のみを取り出す処理を書いてみる。

// alcoholがhighballの時だけtrueを返す
function isSake(alcohol) {
    return alcohol  === "highball";
}
// highballだけ取り出す
function filterSake(alcohols) {
    const alcohol_cases = [];
    for (let i = 0; i < alcohols.length; i++) {
        const sake = liquors[i];
        // highballではないなら次の条件へ
        if (!isSake(sake)) {
            continue;
        }
        // sakeをalcohol_casesに追加
        alcohol_cases.push(sake);
    }
    return alcohol_cases;
}
const liquors = ["beer", "highball", "wine", "softdrink"];
console.log(filterSake(liquors));
#["highball"]

continue文だと少々記述が長くなってしまうが、filterメソッドを使うとより簡潔に書くことができる。

function isHighball(alcohol) {
    return alcohol  === "highball";
}

const alcohols = ["wine","beer","highball","sake"];
console.log(alcohols.filter(isHighball));
#["highball"]

for...in文

for...in文はオブジェクトのプロパティに対して、反復処理を行う。

for (プロパティ in オブジェクト) {
    実行する文;
}

オブジェクトの中身を取り出して、新しい文を作成することができる。

const obj = {
     weak: 1,
    normal: 2,
    strong: 3
};
for (const key in obj) {
    const value = obj[key];
    console.log(`key:${key}, value:${value}`);
}

Object.keysを使っても同様の結果を出力することができる。

const obj = {
    "a": 1,
    "b": 2,
    "c": 3
};
Object.keys(obj).forEach(key => {
    const value = obj[key];
    console.log(`key:${key}, value:${value}`);
});

for... of

for...in文とは異なり、インデックス値ではなく配列の値を列挙する。

Arrayのようなiterableオブジェクトを一つづつ取り出す。

const str = "酒豪戦士ゴウカイジャー";
for (const value of str) {
    console.log(value);
}

#酒
#豪
#戦
#士
#ゴ
#ウ
#カ
#イ
#ジ
#ャ
#ー

所感

早くリファクタリングに使えそうなメソッドを探し出したい、、今書いてあるコードが冗長すぎて恥ずかしい、、

https://github.com/subaru-hello/Zeroken/issues/75

ループと反復処理