簡體   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