Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ramda group then convert siblings to children

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.

like image 913
JK. Avatar asked Jan 31 '26 10:01

JK.


1 Answers

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.

like image 163
Scott Sauyet Avatar answered Feb 02 '26 23:02

Scott Sauyet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!