辞書に照らし合わせて指定文字列を変換する JavaScript

フォーム上の入力値 (ラジオボタンの選択項目など) を REST API に送る際、画面と API の名称や値に関する仕様の差異を吸収するため、「hoge と入力されたら fugafoo と入力されたら bar といった文字列を送信する」といった実装を組み込む必要が出てしまった。

愚直に実装しようとすると、inputStr.replace(/hoge/u, 'fuga') みたいな実装になりそうだが、replace() を重ねがけしていくのは微妙な気がしたのと、変換したい文言の内容がちょくちょく変わりそうだったので、変換処理自体は固定のまま、変換する文言の情報を辞書的に登録しやすくする実装を考えた。

それがコチラ。

/** 変換辞書の配列 : `source` に合致する文言を受け取ったら `replacement` の文言に変換する */
const dictionaryArray = [
  {
    source: 'スタート',
    replacement: 'START'
  },
  {
    source: 'ストップ',
    replacement: 'STOP'
  }
];

/**
 * 文言を変換辞書に照らし合わせ、変換した文言を返す
 * 
 * @param {string} text 変換したい文言
 * @return {string} 変換した文言。変換辞書に該当しなければ元の文言をそのまま返す
 */
function replaceTextFromArray(text) {
  // 引数 `message` が変換辞書の `source` と一致するか検証する
  const matchedObject = dictionaryArray.find((pair) => {
    return pair.source === text;
  });
  // 変換辞書に一致する文言があれば、その置換後の文言を返す
  if(matchedObject) {
    return matchedObject.replacement;
  }
  // そうでなければ元の `message` をそのまま返す
  return text;
}

// 使用例
console.log( replaceTextFromArray('スタート') );  // → 'START'
console.log( replaceTextFromArray('ストップ') );  // → 'STOP'
console.log( replaceTextFromArray('デタラメ') );  // → 'デタラメ'
/** 変換辞書の連想配列 : `source` に合致する文言を受け取ったら `replacement` の文言に変換する */
const dictionaryObject = {
  start: {
    source: 'スタート',
    replacement: 'START'
  },
  stop: {
    source: 'ストップ',
    replacement: 'STOP'
  }
};

/**
 * 文言を変換辞書に照らし合わせ、変換した文言を返す
 * 
 * @param {string} text 変換したい文言
 * @return {string} 変換した文言。変換辞書に該当しなければ元の文言をそのまま返す
 */
function replaceTextFromObject(text) {
  // 引数 `message` が変換辞書の `source` と一致するか検証する
  const matchedKey = Object.keys(dictionaryObject).find((key) => {
    return dictionaryObject[key].source === text;
  });
  // 変換辞書に一致する文言があれば、その置換後の文言を返す
  if(matchedKey) {
    return dictionaryObject[matchedKey].replacement;
  }
  // そうでなければ元の `message` をそのまま返す
  return text;
}

// 使用例
console.log( replaceTextFromObject('スタート') );  // → 'START'
console.log( replaceTextFromObject('ストップ') );  // → 'STOP'
console.log( replaceTextFromObject('デタラメ') );  // → 'デタラメ'

replace-text-from-array.js の方は、source (変換前の文言・検索対象) と replacement (変換後の文言) というプロパティを持つ連想配列を、配列で定義している。変換辞書が配列形式なので、Array#find() を利用して変換したい文言を調べている、というワケ。

replace-text-from-object.js の方も考え方は同じようなモノだが、変換辞書とする変数の形が違う。sourcereplacement のペアを Value に取る、全体が連想配列な構造。連想配列から find() したい場合は、Object.keys() でキー名 (プロパティ名) の配列を作ってループしてやれば良い。

一度作ってしまえばなんてことないのだが、ありがちな2パターンのデータ構造に合わせて同等の結果を得られるスニペットコードを作ってみた次第。