JavaScriptでソート済み配列を連続範囲のシーケンス文字列に変換する方法
はじめに
JavaScriptでは、ソート済みの数値配列から、連続する数値を「開始-終了」の形式で圧縮したシーケンス文字列を作成したいケースがあります。本記事では、そのような変換を行う関数の実装方法を解説します。
問題の定義
次のような、連続する数値を含むソート済み配列を考えてみましょう。
const arr = [1, 2, 3, 5, 7, 8, 9, 11];
この配列を受け取り、シーケンス形式の文字列を生成するJavaScript関数を作成します。
ルールは以下の通りです。
- 連続している要素(例:1, 2, 3)は、最初と最後の数字だけを残し、間をハイフン(
-)でつなぐ - 連続していない単独の数字(例:5)はそのまま出力する
- 各グループはカンマ(
,)で区切る
上記の配列の場合、期待される出力は次のようになります。
const output = '1-3,5,7-9,11';
ここで注目すべきポイントは以下の3つのグループに分かれている点です。
- 「1〜3」→ 連続しているため 1-3
- 「5」→ 単独のため 5
- 「7〜9」→ 連続しているため 7-9
- 「11」→ 単独のため 11
実装コード
この問題は、配列のreduce()メソッドを使うことで簡潔に解決できます。隣接する要素が連続しているかどうかを判定し、連続の始まりをポインタで記録しておくのがポイントです。
const arr = [1, 2, 3, 5, 7, 8, 9, 11];
const buildSequence = (arr = []) => {
let pointer;
return arr.reduce((acc, val, ind) => {
// 次の要素が連続している場合
if (val + 1 === arr[++ind]) {
if (pointer == null) {
pointer = val; // 連続範囲の開始位置を記録
}
return acc;
}
// 連続していた場合は範囲として出力
if (pointer) {
acc.push(`${pointer}-${val}`);
pointer = null;
return acc;
}
// 単独の要素はそのまま追加
acc.push(val);
return acc;
}, []).join(',');
}
console.log(buildSequence(arr));コードの解説
処理の流れを順番に見ていきましょう。
1. ポインタによる範囲の追跡
変数pointerは、現在進行中の連続範囲の開始値を保持します。まだ範囲が始まっていない場合はnullのままです。
2. 連続判定
val + 1 === arr[++ind]という条件で、「現在の値に1を足したものが次の要素と一致するか」を確認しています。一致すれば連続中なので、開始位置だけ記録し、蓄積配列には何も追加しません。
3. 範囲の出力
連続が途切れたタイミングで、pointerが設定されていれば「開始値-終了値」の形式で文字列を作成し、結果配列に追加します。
4. 最終的な結合
すべての要素を処理した後、join(',')で各グループをカンマ区切りの1つの文字列にまとめます。
実行結果
コンソールに出力される結果は次の通りです。
1-3,5,7-9,11
期待どおり、連続する数値が範囲形式に圧縮されたシーケンス文字列が得られました。
まとめ
この記事では、ソート済み配列から連続範囲をハイフンで結合したシーケンス文字列を生成する方法を紹介しました。reduce()とポインタ変数を組み合わせることで、一度のループで効率的に処理できます。同様のテクニックは、日付範囲やIDリストの圧縮表示など、さまざまな場面で応用できるので、ぜひ活用してみてください。
-
JavaScriptのarray.keys()メソッドの使い方と実行例をわかりやすく解説
JavaScriptのarray.keys()メソッドとは JavaScriptのarray.keys()メソッドは、配列のキー(インデックス番号)を格納したArray Iteratorオブジェクトを返すメソッドです。戻り値はイテレータであるため、for...of文などを使って順番に値を取り出して利用します。 構文 array.keys() 引数は不要で、呼び出された配列の各要素のインデックス(0から始まる番号)を持つイテレータが返されます。 サンプル1:車種リストのキーを表示する 次の例では、「Crossover」「Convertible」「Hatchback」「SUV」という4つの車種
-
JavaScriptのArray.isArray()メソッドとは?オブジェクトが配列かどうかを判定する方法
JavaScriptのArray.isArray()メソッドは、指定したオブジェクトが配列であるかどうかを判定するためのメソッドです。判定結果は真偽値として返され、配列であれば true、それ以外の場合は false を返します。typeof 演算子では配列も「object」と判定されてしまうため、正確に配列を見分けたい場面では Array.isArray() が最適な方法となります。基本構文Array.isArray(ob)引数の ob には、判定対象となるオブジェクトを指定します。サンプルコード①:ボタン操作で配列判定を行う <!DOCTYPE html> <html&g