日々の開発では、配列をグループ化する必要があることがよくありますが、そのたびにグループ化関数を手動で記述するか、lodash 関数をgroupBy
使用する必要があります。良いニュースは、JavaScript が新しいグループ化メソッドを導入していることです:Object.groupBy
とMap.groupBy
。グループ化関数を手動で記述する必要はなくなりました。最新バージョンの Chrome (117) はすでにこれら 2 つのメソッドをサポートしています。
以前の配列のグループ化
年齢別にグループ化する必要がある人々を表すオブジェクトの配列があるとします。これはループを使用してforEach
実現できます。コードは次のとおりです。
const people = [
{ name: "Alice", age: 28 },
{ name: "Bob", age: 30 },
{ name: "Eve", age: 28 },
];
const peopleByAge = {};
people.forEach((person) => {
const age = person.age;
if (!peopleByAge[age]) {
peopleByAge[age] = [];
}
peopleByAge[age].push(person);
});
console.log(peopleByAge);
出力は次のとおりです。
{
"28": [{"name":"Alice","age":28}, {"name":"Eve","age":28}],
"30": [{"name":"Bob","age":30}]
}
次のメソッドも使用できますreduce
。
const peopleByAge = people.reduce((acc, person) => {
const age = person.age;
if (!acc[age]) {
acc[age] = [];
}
acc[age].push(person);
return acc;
}, {});
いずれにせよ、コードは少し面倒です。グループ化キーが存在するかどうかオブジェクトがチェックされるたびに、存在しない場合は空の配列が作成され、項目が配列に追加されます。
Object.groupBy を使用したグループ化
新しいObject.groupBy
メソッドは次のように使用できます。
const peopleByAge = Object.groupBy(people, (person) => person.age);
ご覧のとおり、コードは非常に簡潔です。
Object.groupBy
ただし、メソッドを使用すると、プロトタイプのないオブジェクトが返される (つまり、プロパティやメソッドを継承しない) ことに注意してください。これは、オブジェクトが、やなどObject.prototype
のプロパティやメソッドを継承しないことを意味します。これにより、プロパティの誤った上書きが回避されますが、一部のオブジェクト関連のメソッドが使用できなくなることも意味します。hasOwnProperty
toString
Object.prototype
const peopleByAge = Object.groupBy(people, (person) => person.age);
console.log(peopleByAge.hasOwnProperty("28"));
// TypeError: peopleByAge.hasOwnProperty is not a function
が呼び出されるとObject.groupBy
、渡されたコールバック関数は文字列またはSymbol
type の値を返す必要があります。コールバック関数が別の型の値を返した場合、その値は文字列にキャストされます。
この例では、コールバック関数は数値age
属性値を返しますが、Object.groupBy
このメソッドではキーが文字列またはSymbol
型である必要があるため、数値は文字列型にキャストされます。
console.log(peopleByAge[28]);
// => [{"name":"Alice","age":28}, {"name":"Eve","age":28}]
console.log(peopleByAge["28"]);
// => [{"name":"Alice","age":28}, {"name":"Eve","age":28}]
Map.groupBy を使用したグループ化
Map.groupBy
ほぼ同じことを行いますがObject.groupBy
、異なる結果タイプを返すだけです。通常のオブジェクトを返すMap.groupBy
代わりに、Map オブジェクトを返します。Object.groupBy
、
const ceo = { name: "Jamie", age: 40, reportsTo: null };
const manager = { name: "Alice", age: 28, reportsTo: ceo };
const people = [
ceo
manager,
{ name: "Bob", age: 30, reportsTo: manager },
{ name: "Eve", age: 28, reportsTo: ceo },
];
const peopleByManager = Map.groupBy(people, (person) => person.reportsTo);
ここでは、人々は上司への報告に従ってグループ化されます。オブジェクトを通じてこのマップからデータを取得する場合、これらのオブジェクトは同じ ID または参照を持っている必要があります。これは、Map がキーを比較するときに厳密な等価性 (===) を使用するためで、同じ参照を持つ 2 つのオブジェクトのみが同じキーを持つと見なされます。
peopleByManager.get(ceo);
// => [{ name: "Alice", age: 28, reportsTo: ceo }, { name: "Eve", age: 28, reportsTo: ceo }]
peopleByManager.get({ name: "Jamie", age: 40, reportsTo: null });
// => undefined
上記の例では、オブジェクトのようなオブジェクトをキーとして使用してceo
マップ内の項目にアクセスしようとすると、ceo
このオブジェクトは以前にマップに格納されていたオブジェクトと同じオブジェクトではないため、対応する値を取得できません。
ブラウザのサポート
これら 2 つのgroupBy
方法は、proposal-array-grouping 提案によって提案されており、現在フェーズ 3 にあり、2024 年に正式な標準になる予定です。
9 月 12 日、これら 2 つの方法をサポートする Chrome 117 がリリースされました。Firefox Nightly は、フラグの背後で両方のメソッドをすでに実装しています。Safari はすでにこれらのメソッドを別の名前で実装しています。これらのメソッドは Chrome で使用できるため、V8 で実装されていることを意味し、次の V8 アップデートで Node で使用できるようになります。
なぜ静的メソッドを使用するのでしょうか?
Object.groupBy
なぜこの機能がの代わりにとして実装されているのか疑問に思われるかもしれませんArray.prototype.groupBy
。提案によると、ライブラリは互換性のないgroupBy
方法でArray.prototype
変更されました。Web 用の新しい API を検討する場合、下位互換性は非常に重要です。数年前、これを実装しようとしていたときにArray.prototype.flatten
、 という事件がありましたSmooshGate
。
実際、静的メソッドを使用する方が将来のスケーラビリティに優れています。Records
およびTuples
提案が実装されると、Record.groupBy
配列を不変レコードにグループ化するためのメソッドを追加できます。
つまり、静的メソッドを使用すると、下位互換性がより適切に維持され、将来さらに多くの機能やデータ構造を追加するための拡張性が向上します。
JavaScript はこれらのギャップを埋め、開発を容易にします。現在、lodash.groupBy
npm ダウンロードは 1 週間あたり 150 万回から 200 万回の範囲にあり、すべてのブラウザーがこの方法をサポートすると、ライブラリをインポートする必要がなくなりますlodash.groupBy
。
過去におすすめしたもの
Next.js 13.5 が正式リリースされ、速度が大幅に向上しました。
マルチピクチャ警告、フロントエンドが身につけるべきブラウザデバッグスキルを公開!
最新のフルスタック Web フレームワークである Remix 2.0 が正式にリリースされました。
大手メーカーがフロントエンドでどのようなテクノロジーを使用しているかを見てみましょう。
1 つのプロジェクトに Vue と React を混在させることはできますか?
1 行のコードにより、ユーザーはフロントエンド コードをデバッグできなくなります。
Bun 1.0 が正式にリリースされ、爆発的なフロントエンドがより高速に動作します。
60 個の CSS セレクターを 1 か所に図解でまとめました。
200元の罰金と100万元以上を没収 You Yuxi: 高品質の中国語文書の重要性 MuskのJDK 21用ハードコア移行サーバー Solon、仮想スレッドは信じられないほど素晴らしい!!! TCP 輻輳制御によりインターネットが節約される OpenHarmony 用の Flutter が登場 Linux カーネルの LTS 期間が 6 年から 2 年に復元される Go 1.22 で for ループ変数エラーが修正される Google は 25 周年を祝う Svelte は「新しい車輪」 - ルーンを構築