ramda. js как делать групповые, считать, сортировать - PullRequest
0 голосов
/ 01 мая 2020

У меня есть сбор данных, например:

[{"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")), но не могу понять, как выполнить сортировку по количеству.

Ответы [ 3 ]

2 голосов
/ 01 мая 2020

Создайте функцию с R.pipe, которая использует R.countBy для получения объекта { [id]: count }, затем преобразует данные в пары и генерирует массив объектов с R.map и R.applySpe c , Затем сортируйте его с помощью 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>
1 голос
/ 01 мая 2020

Очевидно, 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 берет массив имен свойств и массив значений и объединяет их в один объект.

0 голосов
/ 01 мая 2020

С ванилью JS вы можете просто использовать уменьшить и карту

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)
...