【JavaScript】文字行列と数値配列から指定位置の文字列を構築する方法
問題
n×n の文字マトリクス(二次元配列)と、正の整数のみで構成された重複のない数値配列を受け取る JavaScript 関数を作成します。
この関数は、数値配列に含まれる 1始まりのインデックス に対応する文字をマトリクスから取り出し、それらを順番につなげて1つの文字列を構築して返す必要があります。
入力データの例
まず、文字マトリクスを見てみましょう。
[ ['a', 'b', 'c', 'd'], ['o', 'f', 'r', 'g'], ['h', 'i', 'e', 'j'], ['k', 'l', 'm', 'n'] ];
次に、数値配列です。
[1, 4, 5, 7, 11]
この場合、関数は 'adore' を返す必要があります。なぜなら、マトリクスを1始まりで数えたとき、1番目・4番目・5番目・7番目・11番目の位置にある文字がそれぞれ a、d、o、r、e だからです。
実装例
以下がそのコードです。
const arr = [
['a', 'b', 'c', 'd'],
['o', 'f', 'r', 'g'],
['h', 'i', 'e', 'j'],
['k', 'l', 'm', 'n']
];
const pos = [1, 4, 5, 7, 11];
const buildString = (arr = [], pos = []) => {
// 二次元配列を一次元配列に展開
const flat = [];
arr.forEach(sub => {
flat.push(...sub);
});
let res = '';
pos.forEach(num => {
res += (flat[num - 1] || '');
});
return res;
};
console.log(buildString(arr, pos));出力結果
コンソールには次のように出力されます。
adore
コードの解説
この実装のポイントを順番に見ていきましょう。
1. 二次元配列のフラット化
forEach ループの中でスプレッド演算子(...)を使い、各行(サブ配列)の要素をすべて flat 配列に追加しています。これにより、4行4列のマトリクスが長さ16の一次元配列になります。
2. インデックスの変換
問題では位置が 1始まり で指定されるため、実際の配列アクセス時には num - 1 として0始まりのインデックスに変換しています。これはオフバイワンエラー(off-by-one error)を防ぐための重要な処理です。
3. 範囲外インデックスへの安全な対応
flat[num - 1] || '' という記述により、指定されたインデックスが配列の範囲外だった場合でもエラーにならず、単純に空文字列が連結されます。undefined を文字列に連結すると "undefined" という意図しない文字列になってしまうため、このフォールバック処理は実務上も有効です。
4. 文字列の連結
各文字を res += ... の形で順次連結し、最終的な結果を返しています。より現代的な書き方としては、map と join を組み合わせる方法もあります。
別の書き方:map + join を使った簡潔な実装
const buildString = (arr = [], pos = []) => {
const flat = arr.flat();
return pos.map(num => flat[num - 1] || '').join('');
};ES2019 で導入された Array.prototype.flat() を使えば、手動のループなしで一次元化できるため、コードがさらにシンプルになります。
まとめ
本記事では、二次元の文字配列と1始まりのインデックス配列から目的の文字列を組み立てる方法を紹介しました。ポイントは次の3つです。
- フラット化:
spread演算子やflat()メソッドで二次元配列を一次元に変換する - インデックス調整:1始まりの指定を
- 1で0始まりに変換する - 安全性の確保:
|| ''によるフォールバックで範囲外アクセスに対応する
同様のパターンは、座標指定での要素抽出や、特定条件に基づくデータ結合など、さまざまな場面で応用できます。
-
JavaScriptで文字の出現頻度に基づいて文字列をエンコードする方法
問題文字列 str を唯一の引数として受け取る JavaScript 関数を作成する必要があります。この関数は、入力文字列をもとに新しい文字列を生成します。元の文字列の中でその文字が1回だけ出現する場合には「(」を、2回以上出現する場合には「)」を、対応する位置に割り当てます。なお、大文字と小文字の違いは無視して判定します。例えば、関数への入力が次の場合 −入力const str = Success;出力const output = )())());考え方入力文字列「Success」を大文字小文字を区別せずに見ると、「s」は3回、「u」は1回、「c」は2回、「e」は1回出現しています。したがっ
-
JavaScriptで配列を電話番号形式の文字列に変換する方法
問題ちょうど10個の正の整数を含む配列 arr を受け取るJavaScript関数を作成することを考えます。この関数は、配列の要素を一般的な電話番号の形式である「(XXX) XXX-XXXX」の文字列に組み立てて返す必要があります。例えば、関数への入力が以下の場合を考えてみましょう。入力const arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0];出力const output = (987) 654-3210;コード例以下がその実装コードです。const arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; const createNumber =