JavaScriptにgroupByが実装されたが、フォールバックが必要

Object.groupBy()とは

Object.groupBy()メソッドは、指定されたコールバック関数が返す文字列値に基づいて、与えられた反復可能オブジェクトの要素をグループ化します。

reduceメソッドを使用してもオブジェクトの要素をグループ化できますが、Object.groupBy()を利用する方がよりシンプルなコードで実装可能です。

Object.groupBy()の使い方

Object.groupBy()は、第1引数に配列オブジェクト、第2引数にコールバック関数を取り、以下のように使用します。

const members = [
  { name: 'uduki', age: 17 },
  { name: 'miku', age: 18 },
  { name: 'mio', age: 17 },
  { name: 'kaede', age: 25 },
  { name: 'rin', age: 16 },
]

function myCallback({ age }) {
  return age < 18 ? '未成年' : '成人'
}

const result = Object.groupBy(members, myCallback)
console.log(result)
// {
//   "未成年": [
//     { name: 'uduki', age: 17 },
//     { name: 'mio', age: 17 },
//     { name: 'rin', age: 16 },
//   ],
//   "成人": [
//     { name: 'miku', age: 18 },
//     { name: 'kaede', age: 25 },
//   ],
// }

一方で、reduceメソッドを使用して同様の結果を得る場合、より複雑なコードが必要になります。これにより、Object.groupBy()の方がコードの可読性が高いことがわかります。

const result = members.reduce((acc, member) => {
  const key = myCallback(member)
  if (!acc[key]) {
    acc[key] = []
  }
  acc[key].push(member)
  return acc
}, {})

Safari対策のためフォールバックが必要

2023年12月現在、SafariはTechnology Previewの段階で最新ブラウザでも使用できません。

この機能が利用可能になったとしても、しばらくの間は後方互換性のためのフォールバック処理が必要です。

古いバージョンのSafariでも対応できるようにするためには、以下のようにフォールバック用の関数を作成し、処理を行います。

const members = [
  { name: 'uduki', age: 17 },
  { name: 'miku', age: 18 },
  { name: 'mio', age: 17 },
  { name: 'kaede', age: 25 },
  { name: 'rin', age: 16 },
]

function myCallback({ age }) {
  return age < 18 ? '未成年' : '成人'
}

function customGroupBy(array, callback) {
  return array.reduce((grouped, item) => {
    const key = callback(item)
    if (!grouped[key]) {
      grouped[key] = []
    }
    grouped[key].push(item)
    return grouped
  }, {})
}

const groupByFunction = Object.groupBy || customGroupBy
const result = groupByFunction(members, myCallback)
console.log(result)
// {
//   "未成年": [
//     { name: 'uduki', age: 17 },
//     { name: 'mio', age: 17 },
//     { name: 'rin', age: 16 },
//   ],
//   "成人": [
//     { name: 'miku', age: 18 },
//     { name: 'kaede', age: 25 },
//   ],
// }

Safariのバージョンが更新され、後方互換性が不要になった場合は、customGroupBy()を使用せずにObject.groupBy()のみで処理するようにコードを書き換えると良いでしょう。