Skip to content

Commit

Permalink
Update groupAndSum.js
Browse files Browse the repository at this point in the history
Documented
  • Loading branch information
MichaelLeeHobbs authored Mar 28, 2023
1 parent 152b1c9 commit 93895b5
Showing 1 changed file with 47 additions and 4 deletions.
51 changes: 47 additions & 4 deletions groupAndSum.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,62 @@
// Author Tony Germano
// Discusion orginated on Mirth Slack from discussion started by nafwa03
/**
* Author Tony Germano
* Discussion originated on Mirth Slack from discussion started by nafwa03
*/

/**
* Groups and sums the elements of an array of objects based on the specified groupByKeys and sumKeys.
* This function takes an array of objects (arr), and groups them based on the specified groupByKeys.
* It then sums the values of sumKeys for each group. The resulting array of objects is returned after
* the grouping and summing.
*
* @param {Array<Object>} arr - The array of objects to be grouped and summed.
* @param {Array<string>} groupByKeys - The object keys used for grouping.
* @param {Array<string>} sumKeys - The object keys used for summing.
* @returns {Array<Object>} The resulting array of objects after grouping and summing.
*
* @example
* const inputArray = [
* { category: 'A', subcategory: 'X', value: 10 },
* { category: 'A', subcategory: 'Y', value: 15 },
* { category: 'A', subcategory: 'X', value: 5 },
* { category: 'B', subcategory: 'X', value: 20 }
* ]
*
* const groupedAndSummed = groupAndSum(inputArray, ['category', 'subcategory'], ['value'])
*
* // Result:
* // [
* // { category: 'A', subcategory: 'X', value: 15 },
* // { category: 'A', subcategory: 'Y', value: 15 },
* // { category: 'B', subcategory: 'X', value: 20 }
* // ]
*/
function groupAndSum(arr, groupByKeys, sumKeys) {
// Function to create a key for grouping based on the groupByKeys
const toGroupKey = o => groupByKeys.map(k => o[k]).join('|')

// Function to create a new result object based on the sourceObj and the required keys
const newResultObject = sourceObj => groupByKeys
.map(k => [k, sourceObj[k]])
.concat(sumKeys.map(k => [k, 0]))
.reduce((targetObj, [k, v]) => (targetObj[k] = v, targetObj), {})
const groupMap = Object.create(null)

// Create an empty groupMap to store the grouped objects
const groupMap = {}

// Reduce the input array to a new array with grouped and summed objects
return arr.reduce((result, currentObject) => {
const key = toGroupKey(currentObject)

// Function to push a new result object into the result array and set its value in the groupMap
const pushSetAndGet = o => (result.push(o), groupMap[key] = o)

// Get the result object from the groupMap, or create a new one and add it to the result array
const resultObject = groupMap[key] || pushSetAndGet(newResultObject(currentObject))

// Sum the values of the sumKeys in the result object
sumKeys.forEach(k => { resultObject[k] += currentObject[k] || 0 })

return result
}, [])
}

0 comments on commit 93895b5

Please sign in to comment.