Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter out unique nested values using ramda

I have a collection of UNIX timestamps that looks like this:

[
  {"start_time":1540458000000, "end_time":1540472400000}, 
  {"start_time":1540458000000, "end_time":1540486800000}, 
  {"start_time":1540458000000, "end_time":1540501200000}, 
  {"start_time":1540472400000, "end_time":1540486800000}, 
  {"start_time":1540472400000, "end_time":1540501200000}, 
  {"start_time":1540486800000, "end_time":1540501200000}
]

I’d like to pick out all the unique values from both start_time and end_time, so I’m left with:

[
  {"start_time":1540458000000}, 
  {"start_time":1540472400000}, 
  {"start_time":1540486800000}
  {"end_time":1540472400000},
  {"end_time":1540486800000}, 
  {"end_time":1540501200000}, 
]

I’ve looked at using something similar using groupBy, pluck, zipObj and more using the answer here. But with no luck unfortunately.

A nice-to-have would be a ramda function that worked without having to be given specific keys.

like image 541
gosseti Avatar asked Oct 19 '18 16:10

gosseti


1 Answers

Another Ramda approach:

const {pipe, map, toPairs, unnest, groupBy, head, uniqBy, last, values, apply, objOf} = R

const uniqTimes = pipe(
  map(toPairs),          //=> [[['start', 1], ['end', 2]], [['start', 1], ['end', 3]], ...]
  unnest,                //=> [['start', 1], ['end', 2], ['start', 1], ['end', 3], ...]
  groupBy(head),         //=> {start: [['start', 1], ['start', 1], ['start', 4], ...], end: [['end', 2], ...]}
  map(uniqBy(last)),     //=> {start: [['start', 1], ['start', 4], ...], end: [['end', 2], ...]}
  values,                //=> [[['start', 1], ['start', 4], ...], [['end', 2], ...]]
  unnest,                //=> [['start', 1], ['start', 4], ..., ['end', 2], ...]
  map(apply(objOf))      //=> [{"start": 1}, {"start": 4}, ..., {"end": 2}, ...]
)

const timestamps = [{"start_time":1540458000000,"end_time":1540472400000},{"start_time":1540458000000,"end_time":1540486800000},{"start_time":1540458000000,"end_time":1540501200000},{"start_time":1540472400000,"end_time":1540486800000},{"start_time":1540472400000,"end_time":1540501200000},{"start_time":1540486800000,"end_time":1540501200000}]

console.log(uniqTimes(timestamps))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

This is how I like to use Ramda: build a pipeline of functions that each do simple transformations.


Update

A comment asked how to generate an output more like

{
   "start_time": [1540458000000, 1540458000000],
   "end_time": [1540472400000, 1540486800000]
}

This should do that for the same input:

const uniqTimes = pipe(
  map(toPairs), 
  unnest,
  groupBy(head),
  map(map(last)),
  map(uniq)
)
like image 126
Scott Sauyet Avatar answered Sep 21 '22 17:09

Scott Sauyet