繁体   English   中英

重构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}
]

我首先定义一个函数,该函数将对象的属性求和,如果它们是数字:

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

然后,您可以使用reduceByCOUNTRY将对象分组在一起,并对每个对象应用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM