重构 if else 语句以使用 Ramda.js 并将键值对分解为对象记录
refactoring if else statement to use Ramda.js & breaking down key value pairs into object records
我想将下面的 reducer 函数转换为使用 ramda。而不是使用 JS if else 语句,我怎么能使用 R.ifElse()
来做到这一点
var groupAndSumBy = (objKey) =>
R.reduce(function(acc, val){
var accKey = val[objKey]
acc = Object.assign({}, acc)
if ( acc.hasOwnProperty(accKey) ){
acc[accKey] = acc[accKey] + totalInvoice(val)
} else {
acc[accKey] = totalInvoice(val)
}
return acc
}, {})
var sumByCountry = groupAndSumBy("MARKET")
var vals =[
{
"COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
},
{
"COUNTRY": "GERMANY",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
},
{
"COUNTRY": "UK",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
},
]
想要的输出如下
sumByCountry(vals)
{
'AUSTRIA': 10778.86,
'GERMANY': 10777.86,
'UK': 10777.86,
}
此外,我想将上面所需的输出分解为单独的记录,这是我无法使用 ramda 实现的。
[
{index:'AUSTRIA', value: 10777.86},
{index:'GERMANY', value: 10777.86},
{index:'UK', value: 10777.86}
]
阿兰!
我认为无论如何您都需要使用 lambda,但是如果您想将 if
语句更改为 Ramda 的语句,这可能是解决方案吗?
它更聪明一点,但选择权在你。
const groupAndSumBy = objKey =>
R.reduce((acc, val) => {
const invoice = totalInvoice(val)
const accKey = val[objKey]
return R.ifElse(
R.has(accKey),
R.assoc(accKey, invoice + acc[accKey]),
R.assoc(accKey, invoice)
)(acc)
}, {})
此函数会将结果准备为您需要的格式:
const groupAndSumBy = objKey => vals => R.pipe(
R.reduce((acc, val) => {
const invoice = totalInvoice(val)
const accKey = val[objKey]
return R.ifElse(
R.has(accKey),
R.assoc(accKey, invoice + acc[accKey]),
R.assoc(accKey, invoice)
)(acc)
}, {}),
R.toPairs,
R.map(p => ({ index: p[0], value: p[1] }))
)(vals)
我会首先定义一个函数,对一个对象的属性求和,如果它们是数字:
const sumObj = compose(sum, values, filter(is(Number)));
sumObj({
"COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
});
//=> 10778.86
然后您可以使用 reduceBy
通过 COUNTRY
将您的对象分组在一起并在每个对象上应用 sumObj
。之后使用 aggregate
将您的对象分解为单独的记录:
var vals = [
{ "COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 },
{ "COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 },
{ "COUNTRY": "GERMANY",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 },
{ "COUNTRY": "UK",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 } ];
const sumObj = compose(sum, values, filter(is(Number)));
const sumObjs = reduceBy((acc, obj) => acc + sumObj(obj), 0, prop('COUNTRY'));
const aggregate = compose(map(zipObj(['index', 'value'])), toPairs, sumObjs);
console.log(
aggregate(vals)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {map, zipObj, reduceBy, prop, compose, sum, applySpec, values, filter, is, toPairs} = R;</script>
我想将下面的 reducer 函数转换为使用 ramda。而不是使用 JS if else 语句,我怎么能使用 R.ifElse()
var groupAndSumBy = (objKey) =>
R.reduce(function(acc, val){
var accKey = val[objKey]
acc = Object.assign({}, acc)
if ( acc.hasOwnProperty(accKey) ){
acc[accKey] = acc[accKey] + totalInvoice(val)
} else {
acc[accKey] = totalInvoice(val)
}
return acc
}, {})
var sumByCountry = groupAndSumBy("MARKET")
var vals =[
{
"COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
},
{
"COUNTRY": "GERMANY",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
},
{
"COUNTRY": "UK",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
},
]
想要的输出如下
sumByCountry(vals)
{
'AUSTRIA': 10778.86,
'GERMANY': 10777.86,
'UK': 10777.86,
}
此外,我想将上面所需的输出分解为单独的记录,这是我无法使用 ramda 实现的。
[
{index:'AUSTRIA', value: 10777.86},
{index:'GERMANY', value: 10777.86},
{index:'UK', value: 10777.86}
]
阿兰!
我认为无论如何您都需要使用 lambda,但是如果您想将 if
语句更改为 Ramda 的语句,这可能是解决方案吗?
它更聪明一点,但选择权在你。
const groupAndSumBy = objKey =>
R.reduce((acc, val) => {
const invoice = totalInvoice(val)
const accKey = val[objKey]
return R.ifElse(
R.has(accKey),
R.assoc(accKey, invoice + acc[accKey]),
R.assoc(accKey, invoice)
)(acc)
}, {})
此函数会将结果准备为您需要的格式:
const groupAndSumBy = objKey => vals => R.pipe(
R.reduce((acc, val) => {
const invoice = totalInvoice(val)
const accKey = val[objKey]
return R.ifElse(
R.has(accKey),
R.assoc(accKey, invoice + acc[accKey]),
R.assoc(accKey, invoice)
)(acc)
}, {}),
R.toPairs,
R.map(p => ({ index: p[0], value: p[1] }))
)(vals)
我会首先定义一个函数,对一个对象的属性求和,如果它们是数字:
const sumObj = compose(sum, values, filter(is(Number)));
sumObj({
"COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23
});
//=> 10778.86
然后您可以使用 reduceBy
通过 COUNTRY
将您的对象分组在一起并在每个对象上应用 sumObj
。之后使用 aggregate
将您的对象分解为单独的记录:
var vals = [
{ "COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 },
{ "COUNTRY": "AUSTRIA",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 },
{ "COUNTRY": "GERMANY",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 },
{ "COUNTRY": "UK",
"TYPE": "SERVICES",
"AMT1": 2555.05,
"AMT2": 2686.48,
"AMT3": 2805.1,
"AMT4": 2732.23 } ];
const sumObj = compose(sum, values, filter(is(Number)));
const sumObjs = reduceBy((acc, obj) => acc + sumObj(obj), 0, prop('COUNTRY'));
const aggregate = compose(map(zipObj(['index', 'value'])), toPairs, sumObjs);
console.log(
aggregate(vals)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {map, zipObj, reduceBy, prop, compose, sum, applySpec, values, filter, is, toPairs} = R;</script>