JavaScriptで英単語から押されたテンキーの番号を検索する方法(電話番号問題の逆)
かつてのテンキー式携帯電話では、数字とアルファベットは以下のように対応付けられていました。
const mapping = {
1: [],
2: ['a', 'b', 'c'],
3: ['d', 'e', 'f'],
4: ['g', 'h', 'i'],
5: ['j', 'k', 'l'],
6: ['m', 'n', 'o'],
7: ['p', 'q', 'r', 's'],
8: ['t', 'u', 'v'],
9: ['w', 'x', 'y', 'z']
};
本記事では、このマッピングを利用して、アルファベット文字列を受け取り、その文字列を入力するために押すべき数字の組み合わせを返すJavaScript関数を作成します。いわば、「電話番号から単語を生成する」問題の逆バージョンです。
要件と出力例
たとえば、次のようなアルファベット文字列が与えられた場合を考えてみましょう。
const str = 'mad';
この場合、期待される出力は以下のようになります。
const output = [6, 2, 3];
これは、'm'が6、'a'が2、'd'が3にそれぞれ対応しているためです。
実装コード
それでは、実際のコードを見ていきましょう。
const mapping = {
1: [],
2: ['a', 'b', 'c'],
3: ['d', 'e', 'f'],
4: ['g', 'h', 'i'],
5: ['j', 'k', 'l'],
6: ['m', 'n', 'o'],
7: ['p', 'q', 'r', 's'],
8: ['t', 'u', 'v'],
9: ['w', 'x', 'y', 'z']
};
const convertToNumeral = (str = '') => {
// 「文字 → 数字」の逆引きマップを作成
const entries = Object.entries(mapping);
const res = entries.reduce((acc, [v, letters]) => {
letters.forEach(l => acc[l] = +v);
return acc;
}, {});
// 各文字に対応する数字へ変換
const result = Array.from(str, (el) => {
return res[el];
});
return result;
};
console.log(convertToNumeral('mad'));
コードの解説
処理の流れは以下の2段階です。
① 逆引きマップの作成:Object.entries()でmappingオブジェクトを「[キー, 値]」ペアの配列に変換し、reduce()を使って「文字をキー、数字を値」とする新しいオブジェクトを構築しています。+vによって、文字列型のキーを数値に変換している点にも注目してください。
② 文字列の変換:Array.from()に文字列とマッピング関数を渡すことで、各文字を対応する数字に一括変換し、結果を配列として取得しています。
実行結果
コンソールには以下のように出力されます。
[ 6, 2, 3 ]
このように、事前に逆引きマップを用意しておくことで、任意のアルファベット文字列を効率よく数字列へ変換できます。大文字・小文字が混在する入力に対応したい場合は、res[el.toLowerCase()]のように小文字へ正規化してから参照するとよいでしょう。
-
JavaScriptで配列から3つの数値の最大積を求める方法
JavaScriptで、数値の配列を引数として受け取る関数を作成することを考えます。この関数は、配列内の任意の3つの要素の組み合わせの中で最も大きな積となる3つの要素を選び出し、その積を返すものとします。 例 入力配列が次の場合を考えてみましょう。 const arr = [-10, 7, 29, 30, 5, -10, -70]; このとき、期待される出力は次のとおりです。 const output = 21000; これは、選ばれる3つの数値が「30」「-10」「-70」であり、30 × (-10) × (-70) = 21000 となるためです。 アプローチのポイント:負の数への対応 こ
-
JavaScriptで各桁が左隣の桁で割り切れるかを判定する方法
問題 数値を受け取り、その各桁が左隣(ひとつ前)の桁で割り切れるかどうかを判定し、真偽値(boolean)の配列として返すJavaScript関数を作成する必要があります。 最初の桁にはそれより前に桁が存在しないため、返される配列の先頭は必ず false となります。 実装例 以下がそのコードです。 const num = 73312; const divisibleByPrevious = (n = 1) => { const str = n.toString(); const arr = [false]; for(let i = 1; i < str.l