ES6 reduce
based version version with the support for function iteratee
.
Works just as expected if the iteratee
function is not provided:
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_
In the context of the OP question:
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_
Another ES6 version which reverses the grouping and uses the values
as keys
and the keys
as the grouped values
:
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_
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.