ramda.js 如何进行groupby、count、sort
ramda.js how to do the groupby, count, sort
我有一个这样的数据集:
[{"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"))
,但我不知道如何按计数排序。
借助 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)
用R.pipe创建一个函数,用R.countBy得到一个{ [id]: count }
的对象,然后将数据转换成对,用[=23]生成一个对象数组=],和 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
接受一组 属性 个名称和一组值,并将它们压缩到一个对象中。
我有一个这样的数据集:
[{"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"))
,但我不知道如何按计数排序。
借助 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)
用R.pipe创建一个函数,用R.countBy得到一个{ [id]: count }
的对象,然后将数据转换成对,用[=23]生成一个对象数组=],和 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
接受一组 属性 个名称和一组值,并将它们压缩到一个对象中。