我需要帮助使用ramda转换对象数组;我想
给出这样的数组:
var arr = [
{
title: "scotty",
age: 22,
score: 54,
hobby: "debugging"
}, {
title: "scotty",
age: 22,
score: 19,
hobby: "debugging"
}
, {
title: "gabriel",
age: 40,
score: 1000
}
];
如果我想按title
分组并在age
上加总,则应返回以下值摘要
var arr = [
{
title: "scotty",
age: 44,
hobby: "debugging",
}
, {
title: "gabriel",
age: 40,
score: 1000
}
];
当未指明的属性值不同时,应省略它们,但如果未指定的属性值相同,则应保留在最终结果中。
**我的解决方案**
/*
* [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);
答案 0 :(得分:4)
要修复groupBy
问题,您需要看到groupBy
采用密钥生成函数函数而不是二元谓词。
所以,例如,
const byTitle = R.groupBy(R.prop('title'));
这可以帮助您完成当前的阻止。如果您需要求助的帮助,请告诉我。
<强>更新强>:
你问我的方法。它与你的确有所不同。我可能会做这样的事情:
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)
或者,如果我想要它更简洁,我可能会切换到:
const sumBy = prop => lift(
reduce((current, val) => evolve({[prop]: add(val[prop])}, current)
))(head, tail)
请注意,sumBy
相对可重用。它并不完美,因为它会在空列表中失败。但在我们的例子中,我们知道groupBy的输出永远不会为密钥创建这样的空列表。任何在空列表中没有失败的版本都需要一种方法来提供默认情况。它简直太丑了。
您可以在 Ramda REPL 上看到这一点。
如果您愿意先使用groupSumBy
和groupOn
拨打电话,则可以使用pipe
或compose
制作更易于阅读的sumOn
版本值,然后使用值调用结果函数,也就是说,如果调用如下所示:
groupSumBy('title', 'age')(people)
// or more likely:
const foo = groupSumBy('title', age)
foo(people)
但我把它作为读者的练习。
答案 1 :(得分:1)
使用ramda group by property和sum结果指定属性
一个选项is to 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));
输出按title
分组,并将age
求和。
{
"scotty": 44,
"gabriel": 40
}