JavaScriptでvalueとgapの2つのプロパティをもとに配列内の値をグループ化する方法
グループ化の対象となるデータ
まず、次のような value(値)と gap(間隔)という2つのプロパティを持つオブジェクトの配列を用意しました。
const arr = [
{ value: 12, gap: 1 },
{ value: 13, gap: 1 },
{ value: 14, gap: 1 },
{ value: 15, gap: 1 },
{ value: 19, gap: 2 },
{ value: 21, gap: 1 },
{ value: 22, gap: 1 },
{ value: 23, gap: 1 },
{ value: 27, gap: 1 },
{ value: 31, gap: 4 },
{ value: 35, gap: 4 },
{ value: 39, gap: 4 },
{ value: 43, gap: 1 },
{ value: 50, gap: 1 },
{ value: 51, gap: 1 },
{ value: 52, gap: 1 },
{ value: 55, gap: 1 },
{ value: 57, gap: 1 },
];要件の整理
今回作成するのは、この配列を受け取り、「直前のオブジェクトの value と gap を足した値が、現在のオブジェクトの value と一致する」という条件を満たす連続したオブジェクトどうしを、ひとつのサブ配列(部分配列)にまとめた新しい配列を返す関数です。
具体例を挙げると、value が 12 のオブジェクトは gap が 1 であり、その次のオブジェクトの value は 13 です。そのため、この2つは同じグループにまとめられ、さらに続く value が 14 と 15 のオブジェクトも順番に同じグループへ追加されていきます。
reduce() メソッドによる実装
問題の内容が理解できたところで、実際のコードを書いていきましょう。ここでは Array.prototype.reduce() メソッドを使用して、目的の配列を構築します。
コード例
const arr = [
{ value: 12, gap: 1 },
{ value: 13, gap: 1 },
{ value: 14, gap: 1 },
{ value: 15, gap: 1 },
{ value: 19, gap: 2 },
{ value: 21, gap: 1 },
{ value: 22, gap: 1 },
{ value: 23, gap: 1 },
{ value: 27, gap: 1 },
{ value: 31, gap: 4 },
{ value: 35, gap: 4 },
{ value: 39, gap: 4 },
{ value: 43, gap: 1 },
{ value: 50, gap: 1 },
{ value: 51, gap: 1 },
{ value: 52, gap: 1 },
{ value: 55, gap: 1 },
{ value: 57, gap: 1 },
];
const groupArray = arr => {
return arr.reduce((acc, val, ind, array) => {
// 累積データと、その最後のインデックスを取得
const { data, currentIndex } = acc;
// 現在のオブジェクトのプロパティ
const { value, gap } = val;
// 直前のオブジェクトのプロパティ
const v = arr[ind-1]?.value;
const g = arr[ind-1]?.gap;
if(ind === 0 || value !== v + g){
// 最後のオブジェクトのインデックスを記録し、新しいサブ配列を追加
const index = data.push([val]) - 1;
return { data, currentIndex: index };
};
data[currentIndex].push(val);
return { data, currentIndex };
}, {
data: [],
currentIndex: 0
}).data;
}
console.log(groupArray(arr));コードのポイント
アキュムレータ(累積オブジェクト)には、グループ化した結果を格納する data 配列と、現在書き込み中のサブ配列の位置を示す currentIndex を持たせています。各要素の処理時には、先頭の要素(インデックス 0)である場合、または前のオブジェクトとの連続性が途切れている場合に新しいサブ配列を生成し、それ以外の場合は既存のサブ配列へ要素を追加していきます。これにより、条件を満たす連続したオブジェクトだけが同一のグループに正しく分類されます。なお、直前の要素の参照にはオプショナルチェーン(?.)を使うことで、先頭要素の処理時にエラーが発生しないようにしています。
出力結果
コンソールには次のように出力されます。
[
[
{ value: 12, gap: 1 },
{ value: 13, gap: 1 },
{ value: 14, gap: 1 },
{ value: 15, gap: 1 }
],
[
{ value: 19, gap: 2 },
{ value: 21, gap: 1 },
{ value: 22, gap: 1 },
{ value: 23, gap: 1 }
],
[ { value: 27, gap: 1 } ],
[
{ value: 31, gap: 4 },
{ value: 35, gap: 4 },
{ value: 39, gap: 4 },
{ value: 43, gap: 1 }
],
[
{ value: 50, gap: 1 },
{ value: 51, gap: 1 },
{ value: 52, gap: 1 }
],
[ { value: 55, gap: 1 } ],
[ { value: 57, gap: 1 } ]
]
-
JavaScriptでIDごとにオブジェクトの配列をグループ化する方法
JavaScriptでオブジェクトの配列をidなどの特定のキーごとにグループ化したい場合、reduce()メソッドを使うと簡潔に実装できます。この記事では、どのプロパティにも対応できる汎用的なgroupBy関数を作成し、実際のサンプルコードとともにその仕組みを詳しく解説します。 reduce()によるグループ化の考え方 reduce()は、配列の各要素を順番に処理しながら、1つの累積値(ここではオブジェクト)を組み立てていくメソッドです。各要素からキーの値を取り出し、その値がまだ結果オブジェクトに存在しなければ新しい配列を作成して、そこへ要素を追加していくことでグループ化を実現します。 サ
-
JavaScriptで値に基づいてオブジェクトをグループ化する方法
JavaScriptでは、reduce()メソッドを活用することで、配列内のオブジェクトを特定の値(プロパティ)に基づいて効率的にグループ化できます。たとえば、複数人のデータを「年齢」ごとにまとめたい場合などに役立ちます。ここでは、実際に動作するサンプルコードをもとに、実装手順と仕組みをわかりやすく解説します。 サンプルコード <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewpo