はじめに

編集

プログラミングにおいて、制御構造はプログラムの流れを制御するための重要な概念です。制御構造を理解し、適切に使用することで、プログラムの動作を柔軟に設計し、複雑な処理を効率的に実装することができます。この章では、主な制御構造である「順次構造」「分岐構造」「反復構造」「パターンマッチング」について、JavaScriptRubyのコード例を交えて解説します。

順次構造

編集

順次構造は、プログラムが上から下に向かって順番に実行される最も基本的な制御構造です。プログラムの基本的な流れは、この順次構造によって成り立っています。

JavaScriptの例

編集
// 順次構造の例
console.log("Hello, World!");  // 1つ目の処理
console.log("This is a sequential structure.");  // 2つ目の処理

Rubyの例

編集
# 順次構造の例
puts "Hello, World!"  # 1つ目の処理
puts "This is a sequential structure."  # 2つ目の処理

分岐構造

編集

分岐構造は、条件に応じてプログラムの実行パスを分岐させる制御構造です。主に「if文」や「switch文(JavaScript)」または「case文(Ruby)」が使用されます。

if文は、指定された条件が真(true)の場合に特定の処理を実行します。条件が偽(false)の場合、else文があればその処理を実行します。

JavaScriptの構文

編集
if (条件式) {
    処理1;
} else {
    処理2;
}

Rubyの構文

編集
if 条件式
    処理1
else
    処理2
end

JavaScriptの例

編集
// if文の例
let age = 18;
if (age >= 20) {
    console.log("You are an adult.");
} else {
    console.log("You are a minor.");
}

Rubyの例

編集
# if文の例
age = 18
if age >= 20
    puts "You are an adult."
else
    puts "You are a minor."
end

elsif(Ruby) / else if(JavaScript)

編集

複数の条件を評価する場合、elsif(Ruby)またはelse if(JavaScript)を使用します。

JavaScriptの例

編集
// else if文の例
let score = 85;
if (score >= 90) {
    console.log("Grade: A");
} else if (score >= 80) {
    console.log("Grade: B");
} else {
    console.log("Grade: C");
}

Rubyの例

編集
# elsif文の例
score = 85
if score >= 90
    puts "Grade: A"
elsif score >= 80
    puts "Grade: B"
else
    puts "Grade: C"
end

switch文(JavaScript) / case文(Ruby)

編集

JavaScriptではswitch文、Rubyではcase文を使用して、複数の条件を簡潔に記述できます。

JavaScriptの例

編集
// switch文の例
let day = 3;
switch (day) {
    case 1:
        console.log("Monday");
        break;
    case 2:
        console.log("Tuesday");
        break;
    default:
        console.log("Other day");
}

Rubyの例

編集
# case文の例
day = 3
case day
when 1
    puts "Monday"
when 2
    puts "Tuesday"
else
    puts "Other day"
end

反復構造

編集

反復構造は、特定の処理を繰り返し実行するための制御構造です。主に「for文」と「while文」が使用されます。

for文

編集

for文は、指定された回数や範囲に応じて処理を繰り返します。

JavaScriptの例

編集
// for文の例
for (let i = 0; i < 5; i++) {
    console.log(<code>Loop ${i}</code>);
}

Rubyの例

編集
# for文の例
for i in 0..4
    puts "Loop #{i}"
end

while文

編集

while文は、指定された条件が真(true)である限り、処理を繰り返します。

JavaScriptの例

編集
// while文の例
let count = 0;
while (count < 5) {
    console.log(<code>Count: ${count}</code>);
    count++;
}

Rubyの例

編集
# while文の例
count = 0
while count < 5
    puts "Count: #{count}"
    count += 1
end

無限ループとbreak

編集

反復構造を使用する際、条件を誤ると無限ループに陥ることがあります。無限ループを防ぐため、breakを使用してループを抜けることができます。

JavaScriptの例

編集
// breakの例
while (true) {
    let userInput = prompt("Enter 'exit' to quit:");
    if (userInput === "exit") {
        break;
    }
}

Rubyの例

編集
# breakの例
while true
    print "Enter 'exit' to quit: "
    user_input = gets.chomp
    if user_input == "exit"
        break
    end
end

パターンマッチング

編集

パターンマッチングは、データの構造や内容に基づいて処理を振り分ける高度な制御構造です。近年の多くの言語でサポートされており、特にデータ処理において強力な機能を提供します。

JavaScriptのパターンマッチング

編集

JavaScriptは、ES2023からデストラクチャリングと条件式を組み合わせた形でパターンマッチングをサポートしています。

オブジェクトパターンマッチング

編集
// オブジェクトパターンマッチングの例
function processUser(user) {
    if (user?.role === 'admin' && user?.permissions?.canEdit) {
        console.log('Admin with edit permissions');
    } else if (user?.role === 'user') {
        console.log('Regular user');
    } else {
        console.log('Unknown user type');
    }
}

// 使用例
processUser({ role: 'admin', permissions: { canEdit: true } });
processUser({ role: 'user' });

配列パターンマッチング

編集
// 配列のデストラクチャリングによるパターンマッチング
function analyzeArray([first, second, ...rest]) {
    if (first === undefined) {
        console.log('Empty array');
    } else if (rest.length > 0) {
        console.log(<code>Array with ${rest.length + 2} elements, starting with ${first}</code>);
    } else {
        console.log(<code>Short array: [${first}${second ? ', ' + second : ''}]</code>);
    }
}

// 使用例
analyzeArray([]);
analyzeArray([1]);
analyzeArray([1, 2]);
analyzeArray([1, 2, 3, 4, 5]);

Rubyのパターンマッチング

編集

Rubyは、バージョン2.7以降で正式なパターンマッチング構文をサポートしています。

基本的なパターンマッチング

編集
# caseを使ったパターンマッチング
case data
in [1, 2, *rest]
  puts "配列: 先頭が1, 2で残りは#{rest}"
in { name: "Alice", age: Integer => age } if age > 20
  puts "Alice (#{age}歳)"
in { name: String => name, role: "admin" }
  puts "管理者: #{name}"
else
  puts "マッチするパターンがありません"
end

複雑なデータ構造のマッチング

編集
# 複雑なデータ構造のマッチング例
def process_response(response)
  case response
  in { status: 200, body: { data: Array => items } }
    puts "成功: #{items.length}件のデータを受信"
  in { status: 404 }
    puts "リソースが見つかりません"
  in { status: Integer => code } if code >= 500
    puts "サーバーエラー: #{code}"
  else
    puts "未知のレスポンス形式"
  end
end

# 使用例
process_response({ status: 200, body: { data: [1, 2, 3] } })
process_response({ status: 404 })
process_response({ status: 500 })

制御構造の組み合わせ

編集

制御構造は、組み合わせることでより複雑な処理を実現できます。例えば、分岐構造と反復構造を組み合わせて、条件に応じて繰り返し処理を行うことができます。

JavaScriptの例

編集
// 制御構造の組み合わせ例
for (let i = 0; i < 10; i++) {
    if (i % 2 === 0) {
        console.log(<code>${i} is even.</code>);
    } else {
        console.log(<code>${i} is odd.</code>);
    }
}

Rubyの例

編集
# 制御構造の組み合わせ例
for i in 0..9
    if i % 2 == 0
        puts "#{i} is even."
    else
        puts "#{i} is odd."
    end
end

練習問題

編集
  1. 順次構造: 3つの異なるメッセージを順番に表示するプログラムをJavaScriptとRubyで作成してください。
  2. 分岐構造: ユーザーに年齢を入力させ、20歳以上かどうかを判定するプログラムをJavaScriptとRubyで作成してください。
  3. 反復構造: 1から100までの数字の合計を計算するプログラムをJavaScriptとRubyで作成してください。
  4. パターンマッチング: 複数の形式の商品データ(配列や異なる構造のオブジェクト)を処理し、統一された形式で表示するプログラムをJavaScriptとRubyで作成してください。
  5. 応用問題: ユーザーに数字を入力させ、その数字が素数かどうかを判定するプログラムをJavaScriptとRubyで作成してください。

まとめ

編集

制御構造は、プログラムの流れを制御するための基本的なツールです。順次構造、分岐構造、反復構造、パターンマッチングを適切に使い分けることで、効率的で読みやすいプログラムを作成できます。特に、パターンマッチングは複雑なデータ処理を簡潔に記述できる強力な機能であり、モダンなプログラミングでは重要な役割を果たしています。