是否有其他解决方案可以在不插入未更改的键值的情况下使用“R.applySpec”?

Is there other solution to use `R.applySpec` without inserting the unchanged keys value?

是否有其他解决方案可以使用 R.applySpec 而无需插入未更改的键值?(无需在示例中键入 id 和 name 键,因为稍后键将动态更改)。谢谢。

这是我的输入数据

const data = [ 
  [ 
    { id: 'data1', name: 'it is data 1', itemId: 'item1' },
    { id: 'data1', name: 'it is data 1', itemId: 'item2' } 
  ],
  [ 
    { id: 'data2', name: 'it is data 2', itemId: 'item1' } 
  ],
  [ 
    { id: 'data3', name: 'it is data 3', itemId: 'item1' },
    { id: 'data3', name: 'it is data 3', itemId: 'item2' } 
  ] 
]

和输出

[ 
  { 
    id: 'data1', // this one doesn't change
    name: 'it is data 1', // this one doesn't change
    itemId: [ 'item1', 'item2' ] 
  },
  { 
    id: 'data2', // this one doesn't change
    name: 'it is data 2', // this one doesn't change
    itemId: [ 'item1' ] 
  },
  { 
    id: 'data3', // this one doesn't change
    name: 'it is data 3', // this one doesn't change
    itemId: [ 'item1', 'item2' ] 
  } 
]

使用Ramda获取输出的解决方案

const result = R.map(
  R.applySpec({
    id: R.path([0, 'id']),
    name: R.path([0, 'name']), // don't need to type id or name again
    itemId: R.pluck('itemId')
  })
)(data)

我们当然可以像这样在 Ramda 中写一些东西:

const convert = map (lift (mergeRight) (head, pipe (pluck ('itemId'), objOf('itemId')))) 

const data = [[{id: 'data1', name: 'it is data 1', itemId: 'item1'}, {id: 'data1', name: 'it is data 1', itemId: 'item2'}], [{id: 'data2', name: 'it is data 2', itemId: 'item1'}], [{id: 'data3', name: 'it is data 3', itemId: 'item1'}, {id: 'data3', name: 'it is data 3', itemId: 'item2'}]]

console .log (convert (data))
.as-console-wrapper {min-height: 100% !important; top: 0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {map, lift, mergeRight, head, pipe, pluck, objOf} = R       </script>

不过,我不确定我是否发现它比 ES6/Ramda 版本更易读:

const convert = map (
  reduce ((a, {itemId, ...rest}) => ({...rest, itemId: [...(a .itemId || []), itemId]}), {})
) 

或纯 ES6 版本:

const convert = data => data .map (
  ds => ds .reduce (
    (a, {itemId, ...rest}) => ({...rest, itemId: [...(a .itemId || []), itemId]}),
    {}
  )
)

关于 applySpec is interesting. This function lets you build a new object out of the old one, but you have to entirely describe the new object. There is another function, evolve 的问题,它保持输入对象的所有属性不变,仅替换那些特别提到的,通过将函数应用于它们的当前值。但是 evolve 中函数的输入只接受当前值,不像 applySpec 可以访问整个原始对象。

我可以看到结合这些行为的功能的一些基本原理。但是对于它应该如何工作,我的脑子里并没有一个清晰的 API。如果你对此有一些想法,想要提出建议,Ramda团队永远是looking for suggestions.