[英]using ramda group by property and sum results on specified property
I need help transforming an array of objects using ramda; 我需要帮助使用ramda转换对象数组; I'd like to 我想
given an array like this: 给出这样的数组:
var arr = [
{
title: "scotty",
age: 22,
score: 54,
hobby: "debugging"
}, {
title: "scotty",
age: 22,
score: 19,
hobby: "debugging"
}
, {
title: "gabriel",
age: 40,
score: 1000
}
];
if I want to group by title
and sum on age
it should return the following summary of values 如果我想按title
分组并按age
,则应返回以下值的摘要
var arr = [
{
title: "scotty",
age: 44,
hobby: "debugging",
}
, {
title: "gabriel",
age: 40,
score: 1000
}
];
when the unspecified property's differ in value they should be omitted, but if unspecified property's are the same in value it should remain in the final result. 当未指定的属性值不同时,应省略它们,但如果未指定的属性值相同,则应保留在最终结果中。
** My Solution ** **我的解决方案**
/*
* [Student]
*/
var arr = [
{
title: "scotty",
age: 22,
score: 54,
hobby: "debugging"
}, {
title: "scotty",
age: 22,
score: 19,
hobby: "debugging"
}
, {
title: "gabriel",
age: 40,
score: 1000
}
];
/*
* String -> [[Student]] -> [Student]
*/
var sumOnProperty = function(property, v){
var sum = (x,y) => x[property] + y[property];
var new_array = [];
v.forEach(arr => {
if(arr.length > 1){
arr[0]["age"] = arr.reduce(sum)
new_array.push(arr[0]);
} else {
if(arr.length != 0){
new_array.push(arr[0]);
}
}
})
return new_array;
}
/*
* String -> String -> [Student] -> [Student]
*/
var groupsumBy = function(groupproperty, sumproperty, arr){
// create grouping
var grouping = R.groupBy(R.prop(groupproperty), arr)
// convert grouping object to array
var result1 = R.valuesIn(grouping);
// sum each grouping and flatten 2d array
var result2 = sumOnProperty(sumproperty, result1);
return result2;
}
groupsumBy("title","age",arr);
To fix your groupBy
problem you need to see that groupBy
takes a key-generation function function and not a binary predicate. 要修复groupBy
问题,您需要看到groupBy
采用密钥生成函数函数而不是二元谓词。
So, for instance, 所以,例如,
const byTitle = R.groupBy(R.prop('title'));
This should get you through your current block. 这应该可以帮助您完成当前的阻止。 If you need help with the summation, let me know. 如果您需要求助的帮助,请告诉我。
Update : 更新 :
You asked for my approach. 你问我的方法。 It does differ from yours a fair bit. 它与你的确有所不同。 I would probably do something like this: 我可能会这样做:
const sumBy = prop => vals => reduce(
(current, val) => evolve({[prop]: add(val[prop])}, current),
head(vals),
tail(vals)
)
const groupSumBy = curry((groupOn, sumOn, vals) =>
values(map(sumBy(sumOn))(groupBy(prop(groupOn), vals)))
)
groupSumBy('title', 'age', people)
Or if I wanted it a little more concise, I might switch to: 或者,如果我想要它更简洁,我可能会切换到:
const sumBy = prop => lift(
reduce((current, val) => evolve({[prop]: add(val[prop])}, current)
))(head, tail)
Note that sumBy
is relatively reusable. 请注意, sumBy
是相对可重用的。 It's not perfect, because it would fail on an empty list. 它并不完美,因为它会在空列表中失败。 But in our case, we know that the output of groupBy will never create such an empty list for a key. 但在我们的例子中,我们知道groupBy的输出永远不会为密钥创建这样的空列表。 And any version which didn't fail on an empty list would need a way to supply the default case. 任何在空列表中没有失败的版本都需要一种方法来提供默认情况。 It simply gets ugly. 它简直变得丑陋。
You can see this in action on the Ramda REPL . 你可以在Ramda REPL上看到这个。
You could probably make a more easily readable version of groupSumBy
using pipe
or compose
if you were willing to call first with the groupOn
and sumOn
values, then call the resulting function with the values, that is, if the invocation looked like this: 如果您愿意首先使用groupOn
和sumOn
值调用,则groupSumBy
使用pipe
或compose
创建更容易阅读的groupSumBy
版本, groupSumBy
使用值调用结果函数,即,如果调用如下所示:
groupSumBy('title', 'age')(people)
// or more likely:
const foo = groupSumBy('title', age)
foo(people)
But I leave that as an exercise for the reader. 但我把它作为读者的练习。
using ramda group by property and sum results on specified property 使用ramda group by属性和sum指定属性的结果
One option is to reduceBy
as follows: 一种选择是reduceBy
如下:
import * as R from "ramda";
const arr = [
{
title: "scotty",
age: 22,
score: 54,
hobby: "debugging"
}, {
title: "scotty",
age: 22,
score: 19,
hobby: "debugging"
}
, {
title: "gabriel",
age: 40,
score: 1000
}
];
const reduction =
R.reduceBy((acc, next) => acc + next.age, 0, (x) => x.title, arr);
console.log(JSON.stringify(reduction, undefined, 2));
The output has grouped by title
and has summed the age
. 输出按title
分组,并将age
相加。
{
"scotty": 44,
"gabriel": 40
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.