JavaScriptで配列内の重複キーの値を合計する方法
はじめに
JavaScriptでは、同じキーを持つ複数のオブジェクトが含まれる配列から、キーごとに値を集計したいケースがよくあります。例えば、次のようなオブジェクトの配列を考えてみましょう。
const arr = [
{'ID-01':1},
{'ID-02':3},
{'ID-01':3},
{'ID-02':5}
];
この配列に対して求められるのは、同一のキーを持つオブジェクト同士の値を合計することです。
したがって、期待される出力は以下のようになります。
const output = [{'ID-01':4}, {'ID-02':8}];
実装の考え方
この問題は、次の手順で解決できます。
- 元の配列を先頭から順にループ処理する
- 各要素のキーが、結果格納用の配列内にすでに存在するかどうかを調べる
- 存在する場合は該当するオブジェクトの値に現在の値を加算し、存在しない場合は新しいオブジェクトとして配列に追加する
サンプルコード
以下がその実装例です。
const arr = [
{'ID-01':1},
{'ID-02':3},
{'ID-01':3},
{'ID-02':5}
];
const indexOf = function(key){
return this.findIndex(el => typeof el[key] === 'number')
};
Array.prototype.indexOf = indexOf;
const groupArray = arr => {
const res = [];
for(let i = 0; i < arr.length; i++){
const key = Object.keys(arr[i])[0];
const ind = res.indexOf(key);
if(ind !== -1){
res[ind][key] += arr[i][key];
}else{
res.push(arr[i]);
};
};
return res;
};
console.log(groupArray(arr));
出力結果
このコードを実行すると、コンソールには次のように表示されます。
[ { 'ID-01': 4 }, { 'ID-02': 8 } ]
コードのポイント
この実装では、Object.keys()を使って各オブジェクトの最初のキーを取得しています。さらに、findIndex()によって数値型プロパティを持つ要素の位置を検索することで、同じキーのオブジェクトが結果配列内にすでに存在するかどうかを判定しています。
キーが見つかれば+=演算子で値を加算し、見つからなければpush()で新規オブジェクトを追加します。こうすることで、キーごとに値が集約された配列を効率よく作成できます。
-
JavaScriptで配列をreduceする方法|reduce()メソッドで配列要素を合計する
JavaScriptのreduce()メソッドは、配列の各要素を先頭から順に処理し、その結果を1つの値にまとめる(畳み込む)ための配列メソッドです。数値の合計を求めるだけでなく、配列からオブジェクトを組み立てたり、条件に応じてデータを集約したりと、幅広い場面で活用されています。reduce()メソッドの基本構文 { return 戻り値; }, 初期値);accumulator(アキュムレータ):直前のコールバック関数が返した値(累積値)。最初のループでは初期値、または配列の第1要素が代入されます。currentValue:現在処理している配列の要素。初期値:累積値の出発点となる値。省略し
-
JavaScriptの+演算子が数値の合計ではなく文字列を連結する原因と対処法
なぜ「+」演算子は加算ではなく連結を行うのか? JavaScriptで「+」記号を使ったのに、数値の合計ではなく文字列が連結されてしまうのは、parseInt()を使用していないことが主な原因です。 テキストボックス(input要素)から取得した値は、たとえ数字を入力していても、すべて文字列型(string)として扱われます。そのため、そのまま「+」演算子で足し合わせると、数値の加算ではなく文字列同士の連結が実行されてしまいます。 これを解決するには、テキストボックスから値を取得した後、parseInt()を使って文字列を整数に変換(パース)する必要があります。 コード例 以下は、parseI