0

I came across underscore library during my work. I want to use _.uniq and _.groupBy function. Can someone explain how these work?

I tried to remove duplicate from array of object based on 1 property, but it did not work.

For example:

array = [{'name': 'a', 'age': 18}, '{'name': 'a', 'age': 18}']

I used like:

uniq_arr =_.uniq(array, 'age') 

--> wanted to take unique object based on "age". ---> Did Not Work

Then wanted to group them based on "name". group_arr = _.groupBy(uniq_arr, 'name').
---> "Worked"

My questions/doubts are:

  1. groupby worked fine for me but uniq did not work. So anyone can explain how to get my expected result using uniq?

  2. If I want to use nested groupBy, how should I write that? I mean the syntax.

Also, It will be a great help, If someone can guide me the proper resource from where I can understand these functions in detail.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
amu61
  • 341
  • 4
  • 12

1 Answers1

1

Your question isn't really about angularjs at all, it is entirely about the underscore-library.

Personally, I believe the documentation of groupBy and uniq explain the functionality pretty well.

groupBy _.groupBy(list, iteratee, [context])

Splits a collection into sets, grouped by the result of running each value through iteratee. If iteratee is a string instead of a function, groups by the property named by iteratee on each of the values.

_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
=> {1: [1.3], 2: [2.1, 2.4]}

uniq _.uniq(array, [isSorted], [iteratee]) Alias: unique

Produces a duplicate-free version of the array, using === to test object equality. In particular only the first occurence of each value is kept. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iteratee function.

_.uniq([1, 2, 1, 4, 1, 3]);
=> [1, 2, 4, 3]

The following snippet explains the result of your examples:

console.log("Test data:");
var array = [
  {'name': 'a', 'age': 18},
  {'name': 'a', 'age': 18},
  {'name': 'a', 'age': 19},
  {'name': 'a', 'age': 20},
  {'name': 'c', 'age': 19},
];
console.log(array);

console.log("_.uniq(array, 'age') -> Removes elements to only hold one of each age (names will be ignored entirely):");
var uniq_arr =_.uniq(array, 'age');
console.log(uniq_arr);

console.log("_.groupBy(array, 'name') -> Creates a dictionary where each name holds an array of all elements that match that name:");
var group_arr = _.groupBy(array, 'name');
console.log(group_arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

As for your question about "nested groupBy", if you simply want to group twice in a row, then you could do something like this:

var array = [
  {'name': 'a', 'age': 18},
  {'name': 'a', 'age': 18},
  {'name': 'a', 'age': 19},
  {'name': 'a', 'age': 20},
  {'name': 'c', 'age': 19},
];

var group_arr = _.groupBy(array, 'name');
for (var key in group_arr) {
  group_arr[key] = _.groupBy(group_arr[key], 'age');
}
console.log(group_arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

Side note: I would suggest switching from underscore to lodash. See differences-between-lodash-and-underscore.

Stanislas
  • 1,893
  • 1
  • 11
  • 26
  • Thanks for your reply. Your example worked perfectly fine . I don't know why unique logic did not work when I used. For nested group -> first group by name , and then on that group again group on age. Sorry, I am not able to give you expected output , as I am not able to visualize the output format. And , thanks for pointing out to use 'lodash' library . I will surely look into that. – amu61 Mar 11 '18 at 06:49
  • @shubham I've added the "nested group" to my answer, assuming that you wanted to group the outer collections by `name` and the inner by `age`. Does this [answer](https://stackoverflow.com/help/accepted-answer) your question? – Stanislas Mar 11 '18 at 17:12
  • this is absolutely correct. I was looking for the same. Thanks a lot. – amu61 Mar 17 '18 at 09:08