使用ramda group by属性和sum指定属性的结果 [英] using ramda group by property and sum results on specified property
问题描述
我需要帮助使用ramda转换对象数组;我想按指定的财产
- 分组
- 加上$ b上的另一个属性给定一个这样的数组:
var arr = [
{
title:scotty,
age:22,
得分:54,
爱好:调试
},{
title:scotty,
年龄:22,
得分:19,
爱好:调试
}
,{
title:gabriel,
年龄:40,
得分:1000
}
];
如果我想按
title
进行分组,总和年龄
它应返回以下值摘要var arr = [
{
title:scotty,
年龄:44,
爱好:调试,
}
,{
标题:gabriel,
年龄:40,
得分:1000
}
];
当未指定的属性值不同时,应省略它们,但如果未指定的属性值相同它应保留在最终结果中。
**我的解决方案**
/ *
* [学生]
* /
var arr = [
{
title:scotty,
年龄:22岁,
得分:54,
爱好:调试
},{
标题:scotty,
年龄:22,
得分:19,
爱好:调试
}
,{
标题:gabriel,
年龄:40,
得分:1000
}
];
/ *
*字符串 - > [[学生]] - > [学生]
* /
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]);
}
}
})
返回new_array;
}
/ *
*字符串 - >字符串 - > [学生] - > [学生]
* /
var groupsumBy = function(groupproperty,sumproperty,arr){
//创建分组
var grouping = R.groupBy(R。 prop(groupproperty),arr)
//将分组对象转换为数组
var result1 = R.valuesIn(分组);
//对每个分组求和并展平2d数组
var result2 = sumOnProperty(sumproperty,result1);
返回result2;
}
groupsumBy(title,age,arr);
解决方案修复
groupBy
您需要看到groupBy
采用密钥生成函数函数而不是二元谓词。
因此,例如,
const byTitle = R.groupBy(R.prop('title'));
这可以帮助您完成当前的阻止。如果您在总结方面需要帮助,请与我们联系。
更新:
你问我的做法。它与你的确有所不同。我可能会这样做:
const sumBy = prop => vals => reduce(
(当前,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)
或者,如果我想要更简洁一点,我可能会切换到:
const sumBy = prop =>提升(
reduce((current,val)=> evolve({[prop]:add(val [prop])},current)
))(head,tail)
请注意
sumBy
是相对可重复使用的。它并不完美,因为它会在空列表中失败。但在我们的例子中,我们知道groupBy的输出永远不会为密钥创建这样的空列表。任何在空列表中没有失败的版本都需要一种方法来提供默认情况。它只是变得丑陋。
你可以在 Ramda REPL 。
您可以使用 groupSumBy 版本/ docs / #piperel =nofollow noreferrer>
pipe
或撰写
如果您愿意先使用groupOn
和sumOn
的值,然后用值调用结果函数,也就是说,如果调用看起来像这样:groupSumBy('title','age')(people)
//或更可能:
const foo = groupSumBy('title',age)
FOO(PEO ple)
但我把它作为读者的练习。
I need help transforming an array of objects using ramda; I'd like to
- group by a specified property
- sum another property on the resulting set
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 onage
it should return the following summary of valuesvar 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 thatgroupBy
takes a key-generation function function and not a binary predicate.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. 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. 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.
You could probably make a more easily readable version of
groupSumBy
usingpipe
orcompose
if you were willing to call first with thegroupOn
andsumOn
values, then call the resulting function with the values, that is, if the invocation looked like this:groupSumBy('title', 'age')(people) // or more likely: const foo = groupSumBy('title', age) foo(people)
But I leave that as an exercise for the reader.
这篇关于使用ramda group by属性和sum指定属性的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!