こんにちは、おかちゃんせんせいです!
以前フリガナをヘボン式ローマ字変換する方法について公開しました。
【GAS】カタカナ表記をパスポートでも使えるヘボン式ローマ字に変換するスクリプト今のところ誤作動がないので、依頼されている次の要望について取り掛かることに。
今回は、
Javascriptでフリガナ一文字単位でイニシャル変換したい件
というテーマでお届けします。
目次
ローマ字変換スクリプトとの組み合わせ
今回のスクリプトについては、GASでも使えるし、kintoneなどでも使うことのできる内容になっています。
前回作成したローマ字変換スクリプトで、名前をローマ字変換してアカウント名を作成できるようになりました。
今回はさらにローマ字変換したものをフリガナ一文字単位でイニシャル変換させます。
例えば、山田太郎さん。
ヘボン式ローマ字変換すると、Yamada Taro。
さらに、苗字部分についてイニシャル変換すると、ymdになります。
サンプルコード
function initial(string){
var arrayedString = string.split('');
var tetraTable = {
'chie' : 'c','deyu' : 'd','tchi' : 't','ttsu' : 't','sshi' : 's'
};
var triTable = {
'shi' : 's','chi' : 'c','tsu' : 't','kya' : 'k','kyu' : 'k','kyo' : 'k',
'sha' : 's','shu' : 's','sho' : 's','cha' : 'c','chu' : 'c','cho' : 'c',
'nya' : 'n','nyu' : 'n','nyo' : 'n','hya' : 'h','hyu' : 'h','hyo' : 'h',
'mya' : 'm','myu' : 'm','myo' : 'm','rya' : 'r','ryu' : 'r','ryo' : 'r',
'gya' : 's','gyu' : 'g','gyo' : 'g','bya' : 'b','byu' : 'b','byo' : 'b',
'pya' : 'p','pyu' : 'p','pyo' : 'p',
'jie' : 'j','tei' : 't','dei' : 'd','fua' : 'f','fui' : 'f','fue' : 'f', 'fuo' : 'f',
'bua' : 'b','bui' : 'b', 'bue' : 'b', 'buo' : 'b',
'mba' : 'mb','mbi' : 'mb','mbu' : 'mb','mbe' : 'mb','mbo' : 'mb',
'mma' : 'mm','mmi' : 'mm','mmu' : 'mm','mme' : 'mm','mmo' : 'mm',
'mpa' : 'mp','mpi' : 'mp','mpu' : 'mp','mpe' : 'mp','mpo' : 'mp',
'kka' : 'k','kki' : 'k','kku' : 'k','kke' : 'k','kko' : 'k',
'ssa' : 's','ssu' : 's','sse' : 's','sso' : 's',
'tta' : 't','tte' : 't','tto' : 't',
'nna' : 'n','nni' : 'n','nnu' : 'n','nne' : 'n','nno' : 'n',
'hha' : 'h','hhi' : 'h','ffu' : 'f','hhe' : 'h','hho' : 'h',
'yya' : 'y','yyu' : 'y','yyo' : 'y',
'rra' : 'r','rri' : 'r','rru' : 'r','rre' : 'r','rro' : 'r',
'wwa' : 'w',
'gga' : 'g','ggi' : 'g','ggu' : 'g','gge' : 'g','ggo' : 'g',
'zza' : 'z','jji' : 'j','zzu' : 'z','zze' : 'z','zzo' : 'z',
'dda' : 'd','ddi' : 'd','ddu' : 'd','dde' : 'd','ddo' : 'd',
'bba' : 'b','bbi' : 'b','bbu' : 'b','bbe' : 'b','bbo' : 'b',
'ppa' : 'p','ppi' : 'p','ppu' : 'p','ppe' : 'p','ppo' : 'p'
};
var biTable = {
'ka' : 'k','ki' : 'k','ku' : 'k','ke' : 'k','ko' : 'k',
'sa' : 's','su' : 's','se' : 's','so' : 's',
'ta' : 't','te' : 't','to' : 't',
'na' : 'n','ni' : 'n','nu' : 'n','ne' : 'n','no' : 'n',
'ha' : 'h','hi' : 'h','fu' : 'f','he' : 'h','ho' : 'h',
'ma' : 'm','mi' : 'm','mu' : 'm','me' : 'm','mo' : 'm',
'ya' : 'y','yu' : 'y','yo' : 'y',
'ra' : 'r','ri' : 'r','ru' : 'r','re' : 'r','ro' : 'r',
'wa' : 'w',
'ga' : 'g','gi' : 'g','gu' : 'g','ge' : 'g','go' : 'g',
'za' : 'z','ji' : 'j','zu' : 'z','ze' : 'z','zo' : 'z',
'da' : 'd','de' : 'd','do' : 'd',
'ba' : 'b','bi' : 'b','bu' : 'b','be' : 'b','bo' : 'b',
'pa' : 'p','pi' : 'p','pu' : 'p','pe' : 'p','po' : 'p',
'ja' : 'j','ju' : 'j','jo' : 'j',
};
var uniTable = {
'a' : 'a','i' : 'i','u' : 'u','e' : 'e','o' : 'o'
};
var initialStr = "";
for(var i = 0; i<=string.length-1; i++){
var flg = 0; // 頭文字を特定するためのフラグ
var str = ""; // フリガナ一文字を特定するための文字列
var value = ''; // アルファベット一文字
// 頭文字を特定する特定するまでループ
while(flg === 0){
str = value + arrayedString[i];
if(tetraTable[str]){
initialStr = initialStr + tetraTable[str];
break;
}else if(triTable[str]){
initialStr = initialStr + triTable[str];
break;
}else if(biTable[str]){
initialStr = initialStr + biTable[str];
break;
}else if(uniTable[str]){
initialStr = initialStr + str;
break;
}else{
value = str;
}
i = i + 1;
}
}
return initialStr;
}
コードの内容を解説
今回キーポイントになるのが、
アルファベットが並んでいる中でフリガナ一文字がどこまでなのかを認識すること
です。
目検すれば、yamadaはyaとmaとdaに分けることができますが、用意されている関数・メソッドには分ける機能は今のところありません。
そこで、自前で変換するスクリプトの出番です。
例外はありますが、フリガナ一文字をローマ字で表すと母音のみの1文字(a, i, u, e, o)から、最大で4文字まであるので、想定される文字を連想配列として格納するのがポイントです。
連想配列についての理解が乏しいと感じる方は、下記サイトを参考にしてみてくださいね。
例えば、下井(shimoi)という苗字の場合には、
3文字のshiはs、2文字のmoはm、1文字のi
はそのままになるように変換する必要があります。
そこまで、まずは変換したいローマ字はsplitで一文字ずつに分割。
var arrayedString = string.split('');
次に、イニシャル変換するために変換する組み合わせを連想配列に格納。
var tetraTable = {
'chie' : 'c','deyu' : 'd','tchi' : 't','ttsu' : 't','sshi' : 's'
};
‘chie’ : ‘c’ については、chieをキーとしてcを値として格納しています。
なので、chieという文字列が含まれているときには、tetraTable[‘chie’] でc という値を取得できるようになります。
同じ容量で、1〜3文字のアルファベットの組み合わせを連想配列で設定します。
続いて、splitでアルファベット1文字に分割した文字列をキーにして、連想配列に合致するものがあるかfor文を回して確認します。
var initialStr = "";
for(var i = 0; i<=string.length-1; i++){
var flg = 0; // 頭文字を特定するためのフラグ
var str = ""; // フリガナ一文字を特定するための文字列
var value = ''; // アルファベット一文字
// 頭文字を特定する特定するまでループ
while(flg === 0){
str = value + arrayedString[i];
if(tetraTable[str]){
initialStr = initialStr + tetraTable[str];
break;
}else if(triTable[str]){
initialStr = initialStr + triTable[str];
break;
}else if(biTable[str]){
initialStr = initialStr + biTable[str];
break;
}else if(uniTable[str]){
initialStr = initialStr + str;
break;
}else{
value = str;
}
i = i + 1;
}
}
ここで重要になるのが、連想配列に設定したキーを確認する順番です。
組み合わせ文字数が一番多い4文字から順番に確認し、どの分岐も見つからなかったらループして次の文字も加えて組み合わせをif文で確認していきます。
例えば、shimoi の場合。
sという文字は uniTable にも合致するキーがないので、一旦valueに格納してもう一度ループします。
次のループでは sh という文字ですが、biTable に合致するキーがないのでさらにもう一度ループ。
次は shi という文字ですが、今度は triTable に合致するキーが見つかるので、shi をキーとして s を取得。
このようにして、フリガナ一文字単位で頭文字を取得して文字連結させていきます。
最後に、戻り値としてinitialStrを返すことで、イニシャルを連結した smi が取得できます。
return initialStr;
同じようなことをやりたいと考える人は少ないかもしれませんが、特定の文字列をキーにして値を取得したいシーンは結構あると思います。
その際には、連想配列を活用する事になると思いますので、少しでも今回の内容が参考になれば幸いです。
最後まで読んでいただき、ありがとうございました!
一つ目は、
侍エンジニア塾
です。
VBAやJavaScript関連でネット検索したことがある方であれば、一度は見かけたことある名前かと思います。
JavaやPython、C言語、VBA、JavaScriptなど、様々なプログラミング言語をオンラインで習得するためのサービスを提供しているところなので、自分が習得したい言語がもしありましたら、無料体験レッスンを受けてみると良いかもしれません。
そこでプロ講師に相談をして、習得するプログラミング言語に対して直接質問するのがベストです。
ストアカ
です。
こちらはあえてプログラミング学習専門ではなく、もっと手軽に学ぶ機会を得るサービスをチョイスしてみました。
VBAやJavaScriptなどのワンツーマンレッスンを開催している講師が多数登録しているので、まずは出費を抑えて学習したいと考えている方にお勧めです。