【JavaScript】配列内の重複する数値間の距離を求める方法
課題の概要
少なくとも1組の重複する数値が含まれる数値の配列を引数として受け取り、配列内に存在するすべての重複ペア間の距離(インデックス番号の差)を求めて返すJavaScript関数を作成することを考えます。
ここでいう「距離」とは、同じ数値が出現するインデックス位置同士の差のことです。例えば、ある数値がインデックス0と3に出現していれば、その距離は3となります。同じ数値が3回以上登場する場合は、隣接する出現位置同士の差の中から最小値を採用します。
実装コード
以下が実際のコード例です。
const arr = [2, 3, 4, 2, 5, 4, 1, 3];
const findDistance = arr => {
var map = {}, res = {};
arr.forEach((el, ind) => {
map[el] = map[el] || [];
map[el].push(ind);
});
Object.keys(map).forEach(el => {
if (map[el].length > 1) {
res[el] = Math.min.apply(null, map[el].reduce((acc, val, ind, arr) => {
ind && acc.push(val - arr[ind - 1]);
return acc;
}, []));
};
});
return res;
}
console.log(findDistance(arr));
実行結果
コンソールへの出力は以下のとおりです。
{ '2': 3, '3': 6, '4': 3 }
コードの解説
この関数の処理の流れは次のとおりです。
- ステップ1:インデックスの記録 — forEachループで配列を走査し、各数値の出現位置(インデックス)をmapオブジェクトに配列として格納します。
map[el] = map[el] || []という記述により、キーが未登録の場合は空の配列で初期化されます。 - ステップ2:重複の判定 — Object.keys()でmapの全キーを走査し、出現回数が2以上の数値だけを処理対象とします。これにより、重複していない数値は自動的に除外されます。
- ステップ3:距離の計算 — reduceメソッドで隣接するインデックス同士の差を順に算出し、Math.min.apply(null, ...)でその最小値を取得します。これが「最も近い重複ペア間の距離」となります。
なお、reduceのコールバック内にある ind && acc.push(...) という条件式は、先頭要素(インデックス0)には比較対象となる前の要素が存在しないため、それをスキップするためのものです。
結果の確認
サンプル配列 [2, 3, 4, 2, 5, 4, 1, 3] の場合、各数値の最小距離は次のように求まります。
- 数値 2:インデックス 0 と 3 → 距離 3
- 数値 3:インデックス 1 と 7 → 距離 6
- 数値 4:インデックス 2 と 5 → 距離 3
- 数値 5 と 1:重複していないため結果には含まれません
このように、オブジェクトを活用して各数値の出現位置をまとめて管理することで、シンプルかつ効率的に重複ペア間の距離を計算できます。配列を2回走査するだけで処理が完了するため、全体の計算量はO(n)の線形時間に抑えられ、大きな配列でも高速に動作します。
-
JavaScriptで指定した範囲内の自然数の配列を生成して返す方法
はじめにこの記事では、[a, b](a ≤ b)という形式の2つの数値からなる配列を受け取り、a から b までのすべての自然数(両端の値を含む)を要素とする配列を返す JavaScript 関数の実装方法を解説します。問題作成する関数は、範囲を指定する配列 [a, b](ただし a ≤ b)を引数として受け取り、その範囲に含まれるすべての自然数を配列として返す必要があります。境界値である a と b 自身も結果に含める点がポイントです。サンプルコード以下が基本的な実装例です。const range = [6, 45]; const naturalBetweenRange = ([lower,
-
JavaScriptで配列内の数値と文字列数値を区別して合計差を計算する方法
問題今回は、整数の数値型と文字列型が混在した配列を受け取るJavaScript関数を作成します。関数の仕様は以下の通りです。文字列として表現された整数をすべて合計する数値型の整数の合計から、その文字列整数の合計を引いた値を返すコード例以下がその実装コードです。const arr = [5, 2, '4', '7', '4', 2, 7, 9]; const integerDifference = (arr = []) => { let res = 0; &n