Ramda.js 中的分组和求和 [英] Grouping and summing in Ramda.js

查看:80
本文介绍了Ramda.js 中的分组和求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个列表:

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 },
];

我想合并两个列表中的数据,按 Id 对它们进行分组,并在结果中使用每个 Id 的最高日期,并对唯一对象(即具有相同 Id 和日期的对象 - 可以每个日期和 ID 只能是一个金额).

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}
]

我对 Ramda 很陌生,但我已经设法使用以下代码合并列表:

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));

用于分组和求和:

// 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);

虽然它看起来确实有效,但我想知道在 Ramda 中是否有更好的方法来解决这个问题?groupBy 的文档表明它在这里没有用.

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.

更新版本:jsFiddle

推荐答案

这里有一个使用 R.reduce 函数来避免副作用的小提琴:http://jsfiddle.net/013kjv54/6/

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)));

这篇关于Ramda.js 中的分组和求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆