RedGiant
RedGiant

Reputation: 4748

Using _.uniqBy to keep an object that has a larger value of a key in lodash

JSFiddle Example

let obj = [{'vote':999,'name':'D'},
           {'vote':341,'name':'A'},
           {'vote':789,'name':'A'},
           {'vote':555,'name':'B'}]

let result = _.uniqBy(obj,(item)=>{
  return item.name
})
result = _.orderBy(result,(item)=>{
  return item.mid
},['desc'])

I want to remove the duplicated By name. In this case I want{'vote':341,'name':'A'} removed because it has fewer votes than the other one. Is there a way to compare the vote values during _.uniqBy?

I have also tried running _.orderBy first before _.uniqBy but there is no guarantee that {'vote':341,'name':'A'} is going to be the one removed.

Example

I'm using lodash 4.3

Upvotes: 2

Views: 3463

Answers (1)

Rajesh
Rajesh

Reputation: 24915

You can try this pure JS approach:

let obj = [{'vote':999,'name':'D'},{'vote':341,'name':'A'},{'vote':789,'name':'A'},{'mid':555,'name':'B'}]
let result = [];
obj.reduce(function(p, c){
  if(p[c.name] === undefined){
    result.push(c);
    p[c.name] = c.vote;
  }
  else if(c.vote > p[c.name]){
    let o = result.find(x=> x.name === c.name);
    o.vote = c.vote
  }
  return p;
}, {});

console.log(result)


Lodash approach

Logic

  • Sort array in ascending order by name and descending order by vote.
  • Now use _.uniqBy as it will pick first occurrence.

Note: I was unable to sort using lodash (4.17) (have not used it much), so I have use pure JS to sort it.

Lodash 4.17

As correctly pointed by @Ori Drori, we should use _.sortedUniqBy instead of _.uniqBy as it is optimised for sorted arrays.

let obj = [{'vote':999,'name':'D'},{'vote':341,'name':'A'},{'vote':789,'name':'A'},{'mid':555,'name':'B'}]

var sortedArray = obj.sort(function(a,b){
  return a.name.localeCompare(b.name) || b.vote - a.vote
});

var result = _.sortedUniqBy(sortedArray, 'name');
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


Lodash 3.10

let obj = [{'vote':999,'name':'D'},{'vote':341,'name':'A'},{'vote':789,'name':'A'},{'mid':555,'name':'B'}]

var result =_.uniq(
              _.sortByOrder(
                obj, 
                ["name", "vote"], 
                ["asc", "desc"]
              ), "name");
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>

Upvotes: 3

Related Questions