ぱ行で会話するための変換プログラムを作成

# 概要

Go言語を勉強しようと思い、簡易的なプログラムを作って学習を進めたいと思います。


今回のテーマは、ぱ行だけで会話したいので、そのための文章を変換するプログラムを作成したいと考えています。具体的には、以下のような変換するプログラムを作成します。


例：**聞こえる 波の音が** → **ぴぽぺぷ ぱぴぽぽぽぱ**

母音がaだったら、「**ぽ**」。母音がiだったら、「**ぴ**」に変換されます。

# プログラム

6つの処理を作成し実装しました。
もっと良い方法や間違っているところがあればご指摘ください。


## 1. ひらがなに変換

**お寿司を食べる** → **おすしをたべる**

ひらがなに変換するには、外部のライブラリが必要なので、今回は長くなってしまうため、機械があれば次回以降の記事に書きたいと思いまう。

## 2. 文字列を分割
**おすしをたべる** → **["お", "す", "し", "を", "た", "べ", "る"]**

Go言語では、配列より動的にサイズを変更できるスライスのほうが柔軟にできるため、スライスで実装しました。


```go
// 文字列を一文字ずつ分解してスライスを返す関数
// Parameters:
//   - s: 分解対象の文字列。
// Returns:
//   - []string: 各文字が1要素として格納されたスライス。
func StringToSlice(s string) []string {
    var result []string
    for _, r := range s {
        result = append(result, string(r))
    }
    return result
}
```

## 3. ローマ字に変換 

**["お", "す", "し", "を", "た", "べ", "る"]**　→ **["o", "su", "shi", "wo", "ta", "be", "ru"]**

ローマ字の変換表を作って機能を実装しました。



```go
// ひらがなをローマ字に変換
// Parameters:
//   - s: 変換対象の文字列スライス。
// Returns:
//   - []string: ローマ字に変換されたスライス
func hiraganaToRomaji(hiragana []string) []string {
	romajiMap := map[string]string{
		"あ": "a", "い": "i", "う": "u", "え": "e", "お": "o",
		"か": "ka", "き": "ki", "く": "ku", "け": "ke", "こ": "ko",
		"さ": "sa", "し": "shi", "す": "su", "せ": "se", "そ": "so",
		"た": "ta", "ち": "chi", "つ": "tsu", "て": "te", "と": "to",
		"な": "na", "に": "ni", "ぬ": "nu", "ね": "ne", "の": "no",
		"は": "ha", "ひ": "hi", "ふ": "fu", "へ": "he", "ほ": "ho",
		"ま": "ma", "み": "mi", "む": "mu", "め": "me", "も": "mo",
		"や": "ya", "ゆ": "yu", "よ": "yo",
		"ら": "ra", "り": "ri", "る": "ru", "れ": "re", "ろ": "ro",
		"わ": "wa", "を": "wo", "ん": "n",
		"が": "ga", "ぎ": "gi", "ぐ": "gu", "げ": "ge", "ご": "go",
		"ざ": "za", "じ": "zi", "ず": "zu", "ぜ": "ze", "ぞ": "zo",
		"だ": "da", "ぢ": "di", "づ": "du", "で": "de", "ど": "do",
		"ば": "ba", "び": "bi", "ぶ": "bu", "べ": "be", "ぼ": "bo",
		"ぱ": "pa", "ぴ": "pi", "ぷ": "pu", "ぺ": "pe", "ぽ": "po",
	}

	var romaji []string
	for _, char := range hiragana {
		if romajiChar, exists := romajiMap[char]; exists {
			romaji = append(romaji, romajiChar)
		} else {
			romaji = append(romaji, char)
		}
	}

	return romaji
}
```


## 4. 母音だけ取り出し

**["o", "su", "shi", "wo", "ta", "be", "ru"]** → **["o", "u", "i", "o", "a", "e", "u"]**

母音の対応表を作っても良かったのですが、特に問題なさそうなのでローマ字の最後の文字だけで判別しています。（aiueoのほかにnも対象になりますが、変換後は「ん」にする予定なので問題ありません）


```go
// スライス内の文字列から母音を取り出す
// Parameters:
//   - strs: 変換対象の文字列スライス。
// Returns:
//   - []string: 各文字列から抽出された母音のスライス
func extractVowels(strs []string) []string {
    var result []string

    for _, s := range strs {
        var char string
        char = string(s[len(s)-1])
        result = append(result, char)
    }
    return result
}
```


## 5. 母音からぱ行に変換

**["o", "u", "i", "o", "a", "e", "u"]** →　**["ぽ", "ぷ", "ぴ", "ぽ", "ぱ", "ぺ", "ぷ"]**

こちらの関数も、ぱぴぷぺぽの他に「ん」にも対応するようにしています。


```go

// スライス内の文字列をひらがなに変換する関数
// Parameters:
//   - s: 変換対象の文字列スライス。
// Returns:
//   - []string: 各文字がひらがなに変換されたスライス
func convertToHiraganaSlice(strs []string) []string {
    var result []string

    // 母音をぱ行に変換するマップ
    hiraganaMap := map[string]string{
        "a": "ぱ",
        "i": "ぴ",
        "u": "ぷ",
        "e": "ぺ",
        "o": "ぽ",
        "n": "ん",
    }

    for _, s := range strs {
        if hiraganaChar, exists := hiraganaMap[s]; exists {
            result = append(result, hiraganaChar)
        } else {
            result = append(result, "") // マッチしない場合に空文字列を追加
        }
    }
    return result
}

```


## 6. スライスの文字を結合
**["ぽ", "ぷ", "ぴ", "ぽ", "ぱ", "ぺ", "ぷ"]** →　**ぽぷぴぽぱぺぷ**

標準ライブラリの**strings**パッケージを使用して実装しています

```go
// 文字列のスライスを結合して1つの文字列を返す関数
// Parameters:
//   - strs: 結合する文字列のスライス
// Returns:
//   - string: 結合された文字列
func JoinStrings(strs []string) string {
    return strings.Join(strs, "")
}
```
# 完成したコード

```go
package main
import (
    "fmt"
    "strings"
)

// 文字列を一文字ずつ分解してスライスを返す関数
// Parameters:
//   - s: 分解対象の文字列。
// Returns:
//   - []string: 各文字が1要素として格納されたスライス。
func StringToSlice(s string) []string {
    var result []string
    for _, r := range s {
        result = append(result, string(r))
    }
    return result
}

// ひらがなをローマ字に変換
// Parameters:
//   - s: 変換対象の文字列スライス。
// Returns:
//   - []string: ローマ字に変換されたスライス
func hiraganaToRomaji(hiragana []string) []string {
	romajiMap := map[string]string{
		"あ": "a", "い": "i", "う": "u", "え": "e", "お": "o",
		"か": "ka", "き": "ki", "く": "ku", "け": "ke", "こ": "ko",
		"さ": "sa", "し": "shi", "す": "su", "せ": "se", "そ": "so",
		"た": "ta", "ち": "chi", "つ": "tsu", "て": "te", "と": "to",
		"な": "na", "に": "ni", "ぬ": "nu", "ね": "ne", "の": "no",
		"は": "ha", "ひ": "hi", "ふ": "fu", "へ": "he", "ほ": "ho",
		"ま": "ma", "み": "mi", "む": "mu", "め": "me", "も": "mo",
		"や": "ya", "ゆ": "yu", "よ": "yo",
		"ら": "ra", "り": "ri", "る": "ru", "れ": "re", "ろ": "ro",
		"わ": "wa", "を": "wo", "ん": "n",
		"が": "ga", "ぎ": "gi", "ぐ": "gu", "げ": "ge", "ご": "go",
		"ざ": "za", "じ": "zi", "ず": "zu", "ぜ": "ze", "ぞ": "zo",
		"だ": "da", "ぢ": "di", "づ": "du", "で": "de", "ど": "do",
		"ば": "ba", "び": "bi", "ぶ": "bu", "べ": "be", "ぼ": "bo",
		"ぱ": "pa", "ぴ": "pi", "ぷ": "pu", "ぺ": "pe", "ぽ": "po",
	}

	var romaji []string
	for _, char := range hiragana {
		if romajiChar, exists := romajiMap[char]; exists {
			romaji = append(romaji, romajiChar)
		} else {
			romaji = append(romaji, char)
		}
	}

	return romaji
}

// スライス内の文字列から母音を取り出す
// Parameters:
//   - strs: 変換対象の文字列スライス。
// Returns:
//   - []string: 各文字列から抽出された母音のスライス
func extractVowels(strs []string) []string {
    var result []string

    for _, s := range strs {
        var char string
        char = string(s[len(s)-1])
        result = append(result, char)
    }
    return result
}


// スライス内の文字列をひらがなに変換する関数
// Parameters:
//   - s: 変換対象の文字列スライス。
// Returns:
//   - []string: 各文字がひらがなに変換されたスライス
func convertToHiraganaSlice(strs []string) []string {
    var result []string

    // 母音をぱ行に変換するマップ
    hiraganaMap := map[string]string{
        "a": "ぱ",
        "i": "ぴ",
        "u": "ぷ",
        "e": "ぺ",
        "o": "ぽ",
        "n": "ん",
    }

    for _, s := range strs {
        if hiraganaChar, exists := hiraganaMap[s]; exists {
            result = append(result, hiraganaChar)
        } else {
            result = append(result, "") // マッチしない場合に空文字列を追加
        }
    }
    return result
}

// 文字列のスライスを結合して1つの文字列を返す関数
// Parameters:
//   - strs: 結合する文字列のスライス
// Returns:
//   - string: 結合された文字列
func JoinStrings(strs []string) string {
    return strings.Join(strs, "")
}

func main(){

    var inputString string = "おすしをたべる"

    // 1. ひらがなに変換
    // TODO: 外部ライブラリを使って実装する

    // 2. 文字列を分割
    hiraganaCharacters := StringToSlice(inputString)

    // 3. ローマ字に変換 
    romajiCharacters := hiraganaToRomaji(hiraganaCharacters)

    // 4. 母音だけ取り出し
    vowelCharacters := extractVowels(romajiCharacters)

    // 5. 母音をもとにぱ行に変換
    paCharacters := convertToHiraganaSlice(vowelCharacters)

    // 6. スライスの文字を結合
    resultString := JoinStrings(paCharacters)

    // 結果を出力
    fmt.Println(resultString)
}
```


# 実行結果

クイズみたいにしてみたので、何が変換されたか考えてみてください！
クリックすると答えが出ます。

<details><summary>ぽんぴぴぱ</summary>

**こんにちは**

</details>

<details><summary>ぱぴぱぱぺぷぽぷぴぺぷ</summary>

**あしたはげつようびです**

</details>

<details><summary>ぱぱぷぺぺぷぱぱぴ</summary>

**はやくねてください**

</details>

# 課題

実は、以下のような課題が残っています。
今後対応していけたらいいなと思っております。


## 「きゃ」などの小さい「ゃ」「ゅ」「ょ」対応
現状の処理だと、「ぴ」 になってしまいます。正しくは「ぱ」です。

## 記号などのひらがな以外の文字以外の対応
ひらがな文字以外が消えてしまうため、変換対象文字以外は残るようにしたいです。

# 終わりに

今回は、文章をぱ行に変換するプログラムをGO言語で作成してみました。
単純な変換処理のつもりが、思った以上に処理の量が多く、プログラムが長くなってしまいました。知らない言語を触るのは楽しいですね。

今後もGO言語学習していきたいともいます。

ここまで読んでいただき、ぱぴぱぽぷぽぱぴぱぴぱ！


# 追記

GitHubにリポジトリを作成しました。
時間があるときに開発を進めていくので、気になる方は見に来てください

https://github.com/ishi720/ConsonantLockLanguage