我有一个数据收集,如。
[{"id":1,"score":4},{"id":2,"score":3},{"id":1,"score":4},{"id":2,"score":3},{"id":3,"score":4},{"id":1,"score":3}]
我希望输出的数据是:
[{"id":1,"count":3},{"id":2,"count":2},{"id":3,"count":1}]
有什么办法可以用Ramda.js来实现这个功能吗?
我尝试使用 countBy(prop("id"))
但我不知道如何按数量进行排序。
用R.pipe创建一个函数,使用R.countBy来获取一个对象,这个对象的属性是 "id"。{ [id]: count }
然后将数据转换为对,用R.map,和R.applySpec生成一个对象数组。然后用R.sortBy对其进行排序。
const { pipe, countBy, prop, toPairs, map, applySpec, head, last, sortBy, descend } = R
const fn = pipe(
countBy(prop('id')),
toPairs,
map(applySpec({
id: pipe(head, Number), // or just id: head if the id doesn't have to be a number
count: last,
})),
sortBy(descend(prop('count'))), // or ascend
)
const arr = [{"id":1,"score":4},{"id":2,"score":3},{"id":1,"score":4},{"id":2,"score":3},{"id":3,"score":4},{"id":1,"score":3}]
const result = fn(arr)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
很明显 countBy
将是解决方案的一部分,如果你使用Ramda。 我就会选择把它管到 toPairs
和 zipObj
来获得最终结果。
const collect = pipe (
countBy (prop ('id')),
toPairs,
map (zipObj (['id', 'count']))
)
const data = [{id: 1, score: 4}, {id: 2, score: 3}, {id: 1, score: 4}, {id: 2, score: 3}, {id: 3, score: 4},{id: 1, score: 3}]
console .log (collect (data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {pipe, countBy, prop, toPairs, map, zipObj} = R </script>
zipObj
接受一个属性名和值的数组,并将它们压缩成一个对象。
在vanillaJS中,你可以简单地使用reduce和Map
const data = [{"id":1,"score":4},{"id":2,"score":3},{"id":1,"score":4},{"id":2,"score":3},{"id":3,"score":4},{"id":1,"score":3}]
const final = [...data.reduce((op,{id,score})=>{
if(op.has(id)){
op.set(id, op.get(id)+1)
} else {
op.set(id,1)
}
return op;
}, new Map()).entries()].map(([id,count])=>({id,count}))
console.log(final)