【问题标题】:Transforming collection using ramda使用 ramda 转换集合
【发布时间】:2017-11-04 09:49:26
【问题描述】:

我想使用 ramba 进行以下转换

输入集合

const vals = [
        {metric: "Sales", measure:100, period_end_date: "2021-12-31", period_type: 'Annual' },
        {metric: "EBT", measure:101,  period_end_date: "2021-12-31", period_type: 'Annual' },
        {metric: "Sales", measure:100, period_end_date: "2021-09-30", period_type: 'Qtr' },
        {metric: "EBT", measure:101,  period_end_date: "2021-09-30", period_type: 'Qtr' }
       ]

输出

 {  
   "2021-09-30|Qtr": [{"Sales": 100}, {"EBT": 101],  
   "2021-12-31|Annual": [{"Sales": 100, }, {"EBT": 101,}] 
 }

我能够非常接近这个

const keyGen = compose(objOf('key'), join('|'),  props(['period_end_date','period_type']))// + '|' + prop("period_type",o) }

const valGen = compose(apply(objOf), R.ap([R.prop('metric'), R.prop('measure')]), of )

const f4 = map(compose(apply(merge), R.ap([keyGen, valGen]), of))

const result =compose(groupBy(prop('key')),f4 ) (vals)

这给了我以下结果

{"2021-09-30|Qtr": [{"Sales": 100, "key": "2021-09-30|Qtr"}, 
                    {"EBT": 101, "key": "2021-09-30|Qtr"}], 
 "2021-12-31|Annual": [{"Sales": 100, "key": "2021-12-31|Annual"}, 
                       {"EBT": 101, "key": "2021-12-31|Annual"}]}

现在我需要从内部集合中删除 key。我想知道是否有更好的选择。

【问题讨论】:

    标签: javascript functional-programming ramda.js


    【解决方案1】:

    也许您应该简化您的代码并只使用一个简单的函数来将您的集合减少到所需的输出?我使用了Array.prototype.reduce,它很容易转化为 Ramda 的功能性、无点、咖喱风格:

    const convert = (acc, item) => {
      const name = `${item.period_end_date}|${item.period_type}`
      if (!acc[name]) acc[name] = []
      acc[name].push({ [item.metric]: item.measure })
      return acc
    }
    
    const transform = R.reduce(convert, {})
    transform(vals)
    

    在没有 Ramda 的情况下运行 sn-p:

    const vals = [{
        metric: "Sales",
        measure: 100,
        period_end_date: "2021-12-31",
        period_type: 'Annual'
      },
      {
        metric: "EBT",
        measure: 101,
        period_end_date: "2021-12-31",
        period_type: 'Annual'
      },
      {
        metric: "Sales",
        measure: 100,
        period_end_date: "2021-09-30",
        period_type: 'Qtr'
      },
      {
        metric: "EBT",
        measure: 101,
        period_end_date: "2021-09-30",
        period_type: 'Qtr'
      }
    ]
    
    const result = vals.reduce((acc, item) => {
      const name = `${item.period_end_date}|${item.period_type}`
      if (!acc[name]) acc[name] = []
      acc[name].push({
        [item.metric]: item.measure
      })
      return acc
    }, {})
    
    console.log(result)

    【讨论】:

      【解决方案2】:

      R.reduceBy 可用于对列表中的项目进行分组,然后减少具有相同键的每组项目。

      const vals = [
        {metric: "Sales", measure:100, period_end_date: "2021-12-31", period_type: 'Annual' },
        {metric: "EBT", measure:101,  period_end_date: "2021-12-31", period_type: 'Annual' },
        {metric: "Sales", measure:100, period_end_date: "2021-09-30", period_type: 'Qtr' },
        {metric: "EBT", measure:101,  period_end_date: "2021-09-30", period_type: 'Qtr' }
      ]
      
      const fn = R.reduceBy(
        (list, {metric, measure}) => R.append({[metric]: measure}, list),
        [],
        ({period_end_date, period_type}) => `${period_end_date}|${period_type}`,
      )
      
      console.log(fn(vals))
      <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

      【讨论】:

        【解决方案3】:

        另一种可能是这样的:

        const vals = [
          {metric: "Sales", measure:100, period_end_date: "2021-12-31", period_type: 'Annual' },
          {metric: "EBT", measure:101,  period_end_date: "2021-12-31", period_type: 'Annual' },
          {metric: "Sales", measure:100, period_end_date: "2021-09-30", period_type: 'Qtr' },
          {metric: "EBT", measure:101,  period_end_date: "2021-09-30", period_type: 'Qtr' }
        ]
        
        const fn = R.pipe(
          R.groupBy(({period_end_date, period_type}) => `${period_end_date}|${period_type}`),
          R.map(R.map(R.lift(R.objOf)(R.prop('metric'), R.prop('measure'))))
        );
        
        console.log(fn(vals))
        <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

        这里的关键点是liftobjOf,这样它就可以处理值的容器,而不是处理,在这种情况下,函数归还他们(prop('metric')prop('measure')。)

        【讨论】:

          猜你喜欢
          • 2016-04-22
          • 1970-01-01
          • 1970-01-01
          • 2018-03-13
          • 2020-12-03
          • 1970-01-01
          • 1970-01-01
          • 2016-12-31
          • 1970-01-01
          相关资源
          最近更新 更多