In ramda.js how can I group and sort a list by a field and then move all but the first item of each group into children of that item?
Eg below where I have grouped by name and sorted by date descending:
[{ id: 1, name: 'bob', date: '2007-03-05', count: 15},
{ id: 2, name: 'bob', date: '2007-03-04', count: 32},
{ id: 3, name: 'bob', date: '2007-03-01', count: 27},
{ id: 4, name: 'jack', date: '2007-03-04', count: 3},
{ id: 5, name: 'jack', date: '2007-02-22', count: 5}]
Into
[{ id: 1, name: 'bob', date: '2007-03-05', count: 15,
children: [{ id: 2, name: 'bob', date: '2007-03-04', count: 32},
{ id: 3, name: 'bob', date: '2007-03-01', count: 27}]
},
{ id: 4, name: 'jack', date: '2007-03-04', count: 3,
children: [{ id: 5, name: 'jack', date: '2007-02-22', count: 5}]
}
]
I know that I can grab the top item of the entire list with R.head and the rest with R.tail, and then add it as a child with R.merge, but I don't know how to grab just the top or tail of a group within a list.
Another approach:
const fn = pipe(
groupBy(prop('name')),
values,
map(lift(assoc('children'))(tail, head))
);
If you want to include the sort in this, you can add this after values,:
map(sort(descend(prop('date')))),
If this is obscure: map(lift(assoc('children'))(tail, head)) you could replace it with the equivalent:
map((group) => assoc('children', tail(group), head(group)))
You can see this in action on the Ramda REPL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With