roger pence

Potentially, each day is crucial in the total development

Search
Advanced Search
Folder to search:
Limit search to one of these properties:

    How to do a group by operation for a JS/TS object 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.