My Website

Groupby Js Function With Reduce

const groupBy = (array, property) =>
	array.reduce(
		(grouped, element) => ({
			...grouped,
			[element[property]]: [...(grouped[element[property]] || []), element]
		}),
		{}
	);

This function is a concise way to group an array of objects based on a specific property. It uses the reduce method to transform the list into a single object where the keys are the unique property values and the values are arrays containing the matching items.

Line-by-Line Breakdown

Line 1: const groupBy = (array, property) =>

  • const groupBy: Declares a constant named groupBy.
  • (array, property) =>: This is an arrow function that takes two arguments:
    • array: The list of items (usually objects) you want to group.
    • property: The specific key (like "category" or "id") you want to use for grouping.

Line 2: array.reduce(

  • .reduce(): An array method used to transform an entire array into a single value (in this case, an object).
  • It iterates through every item in the array and builds up an "accumulator" result.

Line 3: (grouped, element) => ({

  • (grouped, element): The two parameters for the reducer callback function:
    • grouped: The accumulator. It holds the state of our grouped object as it's being built.
    • element: The current item from the array being processed.
  • => ({: The parenthesis before the curly brace ( is a shortcut in arrow functions that tells JavaScript to implicitly return the object inside.

Line 4: ...grouped,

  • ... (Spread Syntax): This creates a shallow copy of the existing grouped object.
  • It ensures that all groups created in previous iterations are carried over into the new version of the object.

Line 5: [element[property]]: [...(grouped[element[property]] || []), element]

This is the "brain" of the function. It does three things at once:

  • [element[property]]:: Uses Computed Property Names. It looks up the value of the grouping property on the current item (e.g., if property is "color" and the item is {color: 'red'}, the key becomes "red").
  • ...(grouped[element[property]] || []):
    • It checks if a group for this value already exists (grouped[element[property]]).
    • If it doesn't exist (returns undefined), it uses an empty array [] instead (the || OR operator).
    • It then "spreads" the existing items of that group into a new array.
  • , element: Appends the current item to the end of that new array.

Line 6 & 7: }), {}

  • }),: Closes the callback function and the object literal.
  • {}: This is the initial value for the reduce method. It tells JavaScript to start with an empty object as our first "accumulator."

Line 8: );

  • Closes the reduce method and the groupBy function.

Example Usage

If you have a list of fruits and want to group them by color:

const fruits = [
  { name: 'apple', color: 'red' },
  { name: 'banana', color: 'yellow' },
  { name: 'cherry', color: 'red' }
];

const result = groupBy(fruits, 'color');

The resulting result object would look like this:

{
  red: [
    { name: 'apple', color: 'red' },
    { name: 'cherry', color: 'red' }
  ],
  yellow: [
    { name: 'banana', color: 'yellow' }
  ]
}

Note on Performance

While this code is very "clean" and readable (functional style), it creates a new object and a new array on every single iteration because of the spread operators (...). For extremely large datasets, a more performant (though less "pretty") approach would be to mutate the object directly. Modern JavaScript also now includes a built-in Object.groupBy() method that does this natively.