javascriptarrayslodashdistinct-values

Converting Lodash's _.uniqBy() to native JavaScript


Here in this snippet I am stuck with as in _.uniqBy(array, iteratee). This

var sourceArray = [ { id: 1, name: 'bob' },
  { id: 1, name: 'bill' },
  { id: 1, name: 'bill' } ,
  {id: 2,name: 'silly'},
  {id: 2,name: 'billy'}]

function uniqBy (inputArray, callback) {
  return inputArray.filter(callback)
}
var inputFunc = function (item) {
  return item.name
}

// var destArray = _.uniqBy(sourceArray,'name')

var destArray = uniqBy(sourceArray, inputFunc)
console.log('destArray', destArray)

What is the solution?


Solution

  • An ES6 uniqBy using Map with a complexity of O(n):

    const uniqBy = (arr, predicate) => {
      const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
    
      return [...arr.reduce((map, item) => {
        const key = (item === null || item === undefined) ?
          item : cb(item);
    
        map.has(key) || map.set(key, item);
    
        return map;
      }, new Map()).values()];
    };
    
    const sourceArray = [
      { id: 1, name: 'bob' },
      { id: 1, name: 'bill' },
      null,
      { id: 1, name: 'bill' } ,
      { id: 2,name: 'silly'},
      { id: 2,name: 'billy'},
      null,
      undefined
    ];
    
    console.log('id string: ', uniqBy(sourceArray, 'id'));
    
    console.log('name func: ', uniqBy(sourceArray, (o) => o.name));