Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lodash get items that has the lowest value under unique id

I have an array of objects that represents a set of tours but there are different prices for the same tour like this:

let tours = [{'id':1, price:200},
             {'id':1, price:300},
             {'id':3, price:150},
             {'id':2, price:110},
             {'id':3, price:120},
             {'id':2, price:100}]

So, I would like to pick the lowest price available by the tour ID and push it into a new array as unique tour with the lowest price. So the result would be:

result = [{'id':1, price:200},
          {'id':3, price:120},
          {'id':2, price:100},]

I tried methods in Lodash like _.minBy()but it returns one from all the array.

like image 652
Ibrahim Mohammed Avatar asked Mar 07 '23 12:03

Ibrahim Mohammed


1 Answers

Lodash Solution

You can _.groupBy() ids, than _.map() the result, and take the lowest of each group with _.minBy():

const tours = [{"id":1,"price":200, prop: 'prop1' },{"id":1,"price":300, prop: 'prop1'},{"id":3,"price":150},{"id":2,"price":110},{"id":3,"price":120},{"id":2,"price":100}];

const result = _(tours)
  .groupBy('id')
  .map((group) => _.minBy(group, 'price'))
  .value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

VanillaJS Solution

Reduce the tours to a Map with the ids as key. On each iteration take the group with lowest price. When done, spread the Map.values() back to an array:

const tours = [{"id":1,"price":200, prop: 'prop1' },{"id":1,"price":300, prop: 'prop1'},{"id":3,"price":150},{"id":2,"price":110},{"id":3,"price":120},{"id":2,"price":100}];
             
const lowest = [...tours.reduce((r, o) => {
  const { id, price } = o;
  const current = r.get(id);
  
  if(!current || price < current.price) r.set(id, { ...o });

  return r;
}, new Map()).values()];

console.log(lowest);
like image 131
Ori Drori Avatar answered Mar 23 '23 01:03

Ori Drori