[英]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}
]
我首先定義一個函數,該函數將對象的屬性求和,如果它們是數字:
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>
阿蘭! 我想你會需要使用反正拉姆達,但如果你想改變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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.