[javascript] Most efficient method to groupby on an array of objects

ES6 reduce based version version with the support for function iteratee.

Works just as expected if the iteratee function is not provided:

_x000D_
_x000D_
const data = [{id: 1, score: 2},{id: 1, score: 3},{id: 2, score: 2},{id: 2, score: 4}]_x000D_
_x000D_
const group = (arr, k) => arr.reduce((r, c) => (r[c[k]] = [...r[c[k]] || [], c], r), {});_x000D_
_x000D_
const groupBy = (arr, k, fn = () => true) => _x000D_
  arr.reduce((r, c) => (fn(c[k]) ? r[c[k]] = [...r[c[k]] || [], c] : null, r), {});_x000D_
_x000D_
console.log(group(data, 'id'))     // grouping via `reduce`_x000D_
console.log(groupBy(data, 'id'))   // same result if `fn` is omitted_x000D_
console.log(groupBy(data, 'score', x => x > 2 )) // group with the iteratee
_x000D_
_x000D_
_x000D_

In the context of the OP question:

_x000D_
_x000D_
const data = [ { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" }, { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" }, { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" }, { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" }, { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" }, { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" }, { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" }, { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" } ]_x000D_
_x000D_
const groupBy = (arr, k) => arr.reduce((r, c) => (r[c[k]] = [...r[c[k]] || [], c], r), {});_x000D_
const groupWith = (arr, k, fn = () => true) => _x000D_
  arr.reduce((r, c) => (fn(c[k]) ? r[c[k]] = [...r[c[k]] || [], c] : null, r), {});_x000D_
_x000D_
console.log(groupBy(data, 'Phase'))_x000D_
console.log(groupWith(data, 'Value', x => x > 30 ))  // group by `Value` > 30
_x000D_
_x000D_
_x000D_

Another ES6 version which reverses the grouping and uses the values as keys and the keys as the grouped values:

_x000D_
_x000D_
const data = [{A: "1"}, {B: "10"}, {C: "10"}]_x000D_
_x000D_
const groupKeys = arr => _x000D_
  arr.reduce((r,c) => (Object.keys(c).map(x => r[c[x]] = [...r[c[x]] || [], x]),r),{});_x000D_
_x000D_
console.log(groupKeys(data))
_x000D_
_x000D_
_x000D_

Note: functions are posted in their short form (one line) for brevity and to relate just the idea. You can expand them and add additional error checking etc.

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to object

How to update an "array of objects" with Firestore? how to remove json object key and value.? Cast object to interface in TypeScript Angular 4 default radio button checked by default How to use Object.values with typescript? How to map an array of objects in React How to group an array of objects by key push object into array Add property to an array of objects access key and value of object using *ngFor

Examples related to group-by

SELECT list is not in GROUP BY clause and contains nonaggregated column .... incompatible with sql_mode=only_full_group_by Count unique values using pandas groupby Pandas group-by and sum Count unique values with pandas per groups Group dataframe and get sum AND count? Error related to only_full_group_by when executing a query in MySql Pandas sum by groupby, but exclude certain columns Using DISTINCT along with GROUP BY in SQL Server Python Pandas : group by in group by and average? How do I create a new column from the output of pandas groupby().sum()?

Examples related to underscore.js

Add property to an array of objects Comparing two arrays of objects, and exclude the elements who match values into new array in JS using lodash .groupBy. how to add your own keys for grouped output? Remove Duplicate objects from JSON Array Lodash .clone and .cloneDeep behaviors find the array index of an object with a specific key value in underscore Bootstrap - Uncaught TypeError: Cannot read property 'fn' of undefined Map over object preserving keys Remove an item from array using UnderscoreJS Find by key deep in a nested array