JavaScriptで配列内の同一要素を1つのインデックスにまとめて合計する方法
問題概要
今回は、数値の配列を受け取り、同じ値を持つすべての要素を1つのインデックスに集約して合計するJavaScript関数を作成します。
例
入力配列が以下の場合を考えてみましょう。
const arr = [20, 10, 15, 20, 15, 10];
この場合、期待される出力は次のとおりです。
const output = [40, 20, 30];
ご覧のとおり、重複していた 20 は 40 に、15 は 30 に、10 は 20 にと、それぞれ1か所にまとめられて合計されています。元の配列における出現順序は維持されます。
実装コード
lastIndexOf() と splice() を組み合わせることで、後方にある同一要素を前方の位置へ統合しながら合計していくことができます。
const arr = [20, 10, 15, 20, 15, 10];
const addSimilar = arr => {
for(let i = 0; i < arr.length; i++){
// 現在の要素と同じ値が、まだ配列の後方に存在する間ループ
while(i !== arr.lastIndexOf(arr[i])){
const ind = arr.lastIndexOf(arr[i]);
// 後方の同一要素を取り除き、その値を現在の位置に加算
arr[i] += arr.splice(ind, 1)[0];
};
};
};
addSimilar(arr);
console.log(arr);コードの解説
- 外側の
forループで配列の各要素を順番に処理します。 arr.lastIndexOf(arr[i])は、現在の値が配列内で最後に出現する位置を返します。それが現在のインデックスiと異なる間は、同じ値がまだ後方に残っていることを意味します。splice(ind, 1)で後方の同一要素を配列から取り除き、戻り値(取り除かれた要素)の値を現在の位置arr[i]に加算します。- これにより、すべての重複値が最初の出現位置に集約されます。
出力結果
コンソールには以下のように出力されます。
[ 40, 20, 30 ]
補足:Map を使った別解
より簡潔で読みやすい実装として、Map を利用する方法もあります。こちらは元の配列を破壊せず、新しい配列を返すため、意図しない副作用を避けたい場合に適しています。
const addSimilar = arr => {
const map = new Map();
for(const num of arr){
map.set(num, (map.get(num) || 0) + num);
}
return [...map.values()];
};
console.log(addSimilar([20, 10, 15, 20, 15, 10]));
// 出力: [ 40, 20, 30 ]用途に応じて、破壊的な処理を行う方法と、非破壊的に新しい配列を生成する方法を選択するとよいでしょう。
-
JavaScriptでスタックに要素をプッシュ(Push)する方法
ここでは、いくつかの小さなヘルパー関数を備えた、次のようなJavaScriptのスタッククラスを考えてみましょう。例class Stack { constructor(maxSize) { // 最大サイズが指定されない場合はデフォルト値を設定 if (isNaN(maxSize)) { maxSize = 1
-
JavaScriptのプロトタイプにメソッドを追加する方法
JavaScriptのプロトタイプにメソッドを追加する方法JavaScriptでは、コンストラクタ関数のprototypeプロパティにメソッドを追加することで、そのコンストラクタから生成されたすべてのインスタンスが同じメソッドを共有できるようになります。各インスタンスに個別にメソッドを定義する必要がなくなるため、メモリの使用量を抑えられ、コードの保守性も向上します。以下は、JavaScriptのプロトタイプにメソッドを追加するコード例です。コード例<!DOCTYPE html> <html lang="ja"> <head> <me