Grouping and summing in Ramda.js
javascript, ramda.js
Solution
Heres a fiddle that uses the R.reduce function to avoid side-effects: http://jsfiddle.net/013kjv54/6/
I only replaced your grouping code with the following:
var result = R.reduce(function(acc, tuple){
acc.push({
StockId: tuple[0],
Reference: R.maxBy(function(record){return new Date(record.Reference)}, tuple[1]).Reference,
Amount: R.reduce(function(acc, record){return acc + record.Amount}, 0, tuple[1])
});
return acc;
}, [], R.toPairs(R.groupBy(function(record){return record.StockId})(mergedData)));
Problem
I've got two lists: ``` var listA = [ { Id: 2, Date: "2014-11-28", Amount: 30 }, { Id: 1, Date: "2014-11-27", Amount: 15 }, { Id: 1, Date: "2014-11-28", Amount: 20 }, ]; var listB = [ { Id: 1, Date: "2014-11-27", Amount: 15 }, { Id: 2, Date: "2014-11-26", Amount: 25 }, ]; ``` I want to combine the data from both lists, grouping them by Id and using the highest date for each Id in the result, and summing the totals of the unique objects (ie. objects with the same Id and Date - there can only be one amount per Date and Id). In other words, I want this result: ``` // "For ID X, the Amounts up to Date Y = total Z" [ {"Id":1,"Date":"2014-11-28","Amount":35}, {"Id":2,"Date":"2014-11-28","Amount":55} ] ``` I'm very new to Ramda, but I've managed to merge the lists using this code: ``` // Helper functions to build predicate list var predicateListFunc = function (props) { return R.allPredicates(R.map(R.curry(R.eqProps), props)); } var compareProperties = R.unapply(predicateListFunc); // Function to merge lists based on object Ids and Dates var mergeLists = R.unionWith(compareProperties("Id", "Date")); // Function to sort in date descending order; used later to facilitate grouping var sortByDateDesc = R.compose(R.reverse, R.sortBy(R.prop("Date"))); // Merge the lists var mergedData = sortByDateDesc(mergeLists(listA, listB)); ``` For grouping and summing: ``` // My original code used a side-effect because I could not get the R.reduce to // work. Turns out it was a typo that prevented the initial list from propagating // correctly. I reimplemented it and spotted the typo after reading Furqan Zafar's // comment) var groupCalc = function (list, item) { var index = R.findIndex(R.propEq("Id", item.Id), list); if (index >= 0) { list[index].Amount += item.Amount; } else list.push(item); return list; }; var groupedList = R.reduce(groupCalc, [], mergedData); ``` While it does appear to work, I'm wondering if there's a better way of solving this problem in Ramda? The documention for groupBy indicates that it's not useful here. Updated version: jsFiddle