JavaScriptにgroupByが実装されたから、Lodashの.groupByと比較してみた
に公開
TL;DR
- JavaScript 標準に
groupBy
関数が実装されました。 - 2023 年 12 月時点で、Safari など一部のブラウザは未対応です。
- Underscore.js や Lodash の
.groupBy()
と同等のコード量と可読性を、ネイティブのみで実現できます。
はじめに
JavaScript 標準に groupBy() が実装されたらしい
プログラミング言語やデータベースクエリでよく使われる groupBy
は、特定の列やキーを指定してデータをグループにまとめる機能です。Python などでは既に標準機能として搭載されています。
これまでは JavaScript で groupBy
と同様の処理を実装するには、以下の方法がありました:
- Underscore.js や Lodash などのライブラリを使用する
reduce()
など、標準で実装された関数を利用する
Underscore.js とは
Underscore.js は JavaScript で使用されるライブラリの一種です。便利な関数を 100 以上も用意していることで人気を集めております。
Lodash とは
Lodash は、軽量な JavaScript ユーティリティライブラリです。配列やオブジェクト、文字列などに対して頻用される処理がモジュールとして用意されています。
実際に比べてみた
Lodash のサンプルコード
Lodash のドキュメントでは以下の二つの実装例が紹介されています。 今回はこのサンプルコードをもとに比較します。
// Lodash var grouped = _.groupBy([6.1, 4.2, 6.3], Math.floor); console.log(grouped); // => { '4': [4.2], '6': [6.1, 6.3] } // The `_.property` iteratee shorthand. var grouped = _.groupBy(['one', 'two', 'three'], 'length'); console.log(grouped); // => { '3': ['one', 'two'], '5': ['three'] }
これまでの代替実装
これまでは reduce()
を用いて以下のように実装する必要がありました。
// Native with reduce() var grouped = [6.1, 4.2, 6.3].reduce( (r, v, i, a, k = Math.floor(v)) => ((r[k] || (r[k] = [])).push(v), r), {} ); console.log(grouped); // => { '4': [4.2], '6': [6.1, 6.3] } // Native with reduce() var grouped = ['one', 'two', 'three'].reduce( (r, v, i, a, k = v.length) => ((r[k] || (r[k] = [])).push(v), r), {} ); console.log(grouped); // => { '3': ['one', 'two'], '5': ['three'] }
Object.groupBy()を用いた代替実装
Object.groupBy()
を用いることで、lodash とほぼ同等の記述量で実装できるようになりました。
また、引数が現在の要素を示すv
のみなので、可読性も向上しています。
// Native with Object.groupBy() var grouped = Object.groupBy([6.1, 4.2, 6.3], (num) => Math.floor(num)); console.log(grouped); // => { '4': [4.2], '6': [6.1, 6.3] } // Native with Object.groupBy() var grouped = Object.groupBy(['one', 'two', 'three'], (v) => v.length); console.log(grouped); // => { '3': ['one', 'two'], '5': ['three'] }
まとめ
今更感はありますが、コード量の削減と可読性の向上が期待できるので、個人的には嬉しい機能追加だと思います。 今後、Safari でも正式サポートされることを期待しています。