JSだけでやる google spreadsheet 用の excelのphonetic()みたいな「カナかな変換」関数

Google spreadsheets 最高ですよね！
データ連携や簡易SQLなど、もうExcelには戻れない要素満載です。

なんですが、ごくたまに欲しい関数が無くて困ったりする事も。
幸いjavascriptでいくらでも関数が追加出来ますので、足りないものは追加しちゃいましょう。

gooのAPIを使う方法などがよく紹介されているのですが、
今回は社内のデータを扱う関係でJavaScriptの埋め込みスクリプトだけで完結したいと思います。
よって機能はカタカナーひらがなーﾊﾝｶｸｶﾀｶﾅの相互変換だけに絞ります。

方法は文字コードから算定するなど色んなやり方があるかと思うのですが、
Pre-Practiceさんの公開されている「Google Apps Script試行錯誤Blog」の記事を拝見しまして、
https://www.pre-practice.net/2017/12/blog-post.html

このやり方が一番直感的だなと思いました。

ついてはこちらのコードを拝借させて頂いて、Arrayformulaなどでも使い易いように整理したいと思います。


```code-kana2kana.js
var hira = ["あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", "さ", "し", "す", "せ", "そ", "た", "ち", "つ", "て", "と", "な", "に", "ぬ", "ね", "の", "は", "ひ", "ふ", "へ", "ほ", "ま", "み", "む", "め", "も", "や", "ゆ", "よ", "ら", "り", "る", "れ", "ろ", "わ", "を", "ん", "が", "ぎ", "ぐ", "げ", "ご", "ざ", "じ", "ず", "ぜ", "ぞ", "だ", "ぢ", "づ", "で", "ど", "ば", "び", "ぶ", "べ", "ぼ", "ぱ", "ぴ", "ぷ", "ぺ", "ぽ", "ぁ", "ぃ", "ぅ", "ぇ", "ぉ", "ゃ", "ゅ", "ょ", "っ", "ゔ"];
var kana = ["ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "パ", "ピ", "プ", "ペ", "ポ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ヴ"];
var hankana = ["ｱ", "ｲ", "ｳ", "ｴ", "ｵ", "ｶ", "ｷ", "ｸ", "ｹ", "ｺ", "ｻ", "ｼ", "ｽ", "ｾ", "ｿ", "ﾀ", "ﾁ", "ﾂ", "ﾃ", "ﾄ", "ﾅ", "ﾆ", "ﾇ", "ﾈ", "ﾉ", "ﾊ", "ﾋ", "ﾌ", "ﾍ", "ﾎ", "ﾏ", "ﾐ", "ﾑ", "ﾒ", "ﾓ", "ﾔ", "ﾕ", "ﾖ", "ﾗ", "ﾘ", "ﾙ", "ﾚ", "ﾛ", "ﾜ", "ｦ", "ﾝ", "ｶﾞ", "ｷﾞ", "ｸﾞ", "ｹﾞ", "ｺﾞ", "ｻﾞ", "ｼﾞ", "ｽﾞ", "ｾﾞ", "ｿﾞ", "ﾀﾞ", "ﾁﾞ", "ﾂﾞ", "ﾃﾞ", "ﾄﾞ", "ﾊﾞ", "ﾋﾞ", "ﾌﾞ", "ﾍﾞ", "ﾎﾞ", "ﾊﾟ", "ﾋﾟ", "ﾌﾟ", "ﾍﾟ", "ﾎﾟ", "ｧ", "ｨ", "ｩ", "ｪ", "ｫ", "ｬ", "ｭ", "ｮ", "ｯ", "ｳﾞ"];

// ベース関数
function kana2kana_single(text, input_type = 'kana', output_type = 'hira') {
  
  var input;
  var output;
  
  switch (input_type) {
    case 'hira': input = hira; break;
    case 'kana': input = kana; break;
    case 'hankana': input = hankana; break;
    default:
      console.log('invalid input_type specified');
  }
  
  switch (output_type) {
    case 'hira': output = hira; break;
    case 'kana': output = kana; break;
    case 'hankana': output = hankana; break;
    default:
      console.log('invalid output_type specified');
  }

  var result = "";
  var array = [];
  
  // 半角カナの場合の濁音と半濁音処理
  for (var i = 0; i < text.length; i++) {
    if (text[i] == "ﾞ" || text[i] == "ﾟ") {
      array[array.length - 1] = (text[i - 1] + text[i]);
    } else {
      array.push(text[i]);
    }
  }
  // ルックアップ処理
  for (var j = 0; j < array.length; j++) {
    var index = input.indexOf(array[j]);
    if (index == -1) {
      result = result + array[j];
    } else {
      result = result + output[index];
    }
  }
  return result;
}



// array対応版
function kana2kana(src_array, input_type = 'kana', output_type = 'hira') {
  
  // 引数無しで呼ばれたら引数をそのままリターン
  if (!src_array) return src_array;
  
  // シングル(atomic)で呼ばれた場合はループせずatomicでリターン
  if (! Array.isArray(src_array)){
      return(kana2kana_single(src_array, input_type.toString(), output_type.toString()));
  }
 
  // 引数はarrayなので順番に処理する
  
  // 空のarrayを初期化
  var results = [[]];

  src_array.forEach(function(item, index){
      results.push(kana2kana_single(item.toString(), input_type, output_type));
  });
  
  // インデックス0はnullが入っているので１つ飛ばしてindex1以降をリターン
  return(results.slice(1))
}

```

使い方はカンタンで、上記をスクリプトエディタにコピペして頂いたら画像のように呼び出します。
ここでは「カタカナ -> ひらがな」変換のみが行われます。
Array対応ですのでarrayformulaを使わずとも直接縦方向に適用出来て便利かなと思っています。
変換したいペアを引数で渡して使います。

![Screenshot 2021-10-18 at 19.22.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255842/43fb37af-228a-6054-0c07-6492699e32f6.png)



また、上記を元に「指定された形に統一して書き出す」関数も用意しました

```code-allkana.js
// ベース関数 - 全て半角カナに統一してから、最後に指定されたケースで出力
function allkana_single(src, output_type = "hankana") {
  var result;
  
  // ひらがなを全て半角カナに
  result = kana2kana(src.toString(), "hira", "hankana");
  // カタカナを全て半角カナに
  result = kana2kana(result.toString(), "kana", "hankana");
  
  // 半角カナを指定されたカタチに
  result = kana2kana(result.toString(), "hankana", output_type);
  
  return(result);
}



// 全て半角カナに統一してから、最後に指定されたケースで出力
function allkana(src_array, output_type = 'hankana') {
  
  // 引数無しで呼ばれたら引数をそのままリターン
  if (!src_array) return src_array;
  
  // シングル(atomic)で呼ばれた場合はループせずatomicでリターン
  if (! Array.isArray(src_array)){
      return(allkana_single(src_array, output_type));
  }
 
  // 引数はarrayなので順番に処理する
  // 空のarrayを初期化
  var results = [[]];

  src_array.forEach(function(item, index){
      results.push(allkana_single(item.toString(), output_type));
  });
  
  // インデックス0はnullが入っているので１つ飛ばしてindex1以降をリターン
  return(results.slice(1))
}

```

こちらは、範囲を指定すると一撃で「hira - ひらがな」「kana - カタカナ」「hankana - 半角ｶﾀｶﾅ」に文字列を整形して出力してくれます：
![Screenshot 2021-10-18 at 19.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255842/2c518766-1bc9-6b39-1587-ee99061e05e4.png)


Google Spreadsheetsは本当に有り難いですね！
これで色々とデータ整理が捗りそうです。

ここで改めて、元記事作者の Pre-Practice 様に改めて敬意とお礼を評させて頂きたいと思います。
最後までお読み頂いてありがとうございました！