简体   繁体   English

使用Ramda转换集合

[英]Transforming collection using ramda

I want to do the following transformation using ramba 我想使用ramba进行以下转换

Input collection 输入集合

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' }
       ]

Output 产量

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

I was able to come pretty close with this 我能够很接近这个

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)

This gives me the following result 这给我以下结果

{"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"}]}

Now I need to remove the key from the inner collections. 现在,我需要从内部集合中删除key I wanted to know if there was a better alternative. 我想知道是否有更好的选择。

Perhaps you should simplify your code and just use one simple function that reduces your collection to the desired output? 也许您应该简化代码,仅使用一个简单的函数将您的集合减少到所需的输出? I used Array.prototype.reduce which is easy translatable to Ramda's functional, point-free, curried style: 我使用了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)

And working snippet without Ramda: 而没有Ramda的工作片段:

 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) 

R.reduceBy can be used to group items in a list and then reduce each group of items that have the same key. 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> 

Another possibility is something like this: 另一种可能性是这样的:

 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> 

The key point here is to lift objOf so that instead of working on values , it works on containers of values , in this case, functions that return them ( prop('metric') and prop('measure') .) 这里的关键点是lift objOf以便它不处理 ,而是处理值的 容器 ,在这种情况下,返回值的函数( prop('metric')prop('measure')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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