Unique count in JavaScript array, sorted by count

I have a list of names in JavaScript. What I would like to do is get a list of unique names, but for this list of unique names you can also calculate how many are in my original list. In addition, I need to sort my final list of unique names by account in descending order (then ascending by name, if some have the same count).

Here is what I have, which is a simple list of strings, which then gives me a list of unique names. From here I’m not sure where to get the calculations or how to sort a unique list by accounts. I think the end result will be either a two-dimensional array of names and counters, or two separate arrays, but I'm not sure how to do this in the best and most efficient way.

This is what I have so far:

Array.prototype.contains = function(v) { for (var i = 0; i < this.length; i++) { if (this[i] === v) return true; } return false; }; Array.prototype.unique = function() { var arr = []; for (var i = 0; i < this.length; i++) { if (!arr.contains(this[i])) { arr.push(this[i]); } } return arr; } var uniqueAuthorNames = allAuthorNames.unique(); uniqueAuthorNames.sort(); 
+2
source share
4 answers

Use a hash map to count unique elements , and then sort the unique elements according to two criteria :

 var names = ["eve", "carl", "adam", "carl"]; var counts = names.reduce((counts, name) => { counts[name] = (counts[name] || 0) + 1; return counts; }, {}); var uniques = Object.keys(counts); uniques.sort((a, b) => counts[a] == counts[b] ? a.localeCompare(b) : counts[b] - counts[a]); console.log(counts); console.log(uniques); 
+3
source

Suppose your array of names is in arr:

 var i; var o = {}; var len = arr.length; for (i=0; i<len; i++) { o[arr[i]] = (o[arr[i]] || 0) + 1; } 

At this point, o will contain each unique name with its counter. Then you can use the solution in Sort JavaScript object by property value

It will be

 var sortable = []; for (var name in o) { sortable.push([name, o[name]]) } sortable.sort(function(a, b) {return b[1] - a[1]}) 
+1
source

This should work on what you need.

 Object.defineProperty (Array.prototype, 'getUniqueSorted', { enumerable: false, value: function () { var uniqarr = []; for (var i in this) { var index = uniqarr.indexOf (this.[i]); if (index == -1) { uniqarr.push (this [i]) } else { uniqarr [index].count = uniqarr.count ? 2 : uniqarr.count+1; } } uniqarr = uniqarr.sort(function(a, b){ return (a.count | 1) - (b.count | 1) }); return uniqarr; } }); 

There are other options to make it more elegant.

  Object.defineProperty (Array.prototype, 'removeDuplicated', { enumerable: false, value: function () { var uniqarr = []; this.reduce(function(accum, current) { if (accum.indexOf(current) < 0) { accum.push(current); } return accum; }, uniqarr); return uniqarr.sort(function(a, b){ return a.count - b.count }); } }); 
+1
source
  var names = ['john', 'paul', 'zack', 'john', 'sam', 'jill', 'paul', 'zack', 'zack']; var myNames = names.slice(0); // duplicate the array for getCount function otherwise sort will mess it up. var myNames = names.sort(function(a, b) { if (getCount(a) !== getCount(b)) { return getCount(b) - getCount(a); // b - a to list larger counts first } if (a > b) { return 1; } return -1; // no case for if a == b because thats caught by getCount() }); /** ** This function computes the number of times an element occur inside the array **/ function getCount(element) { var count = 0; for (var n = 0; n < myNames.length; n++) { if (myNames[n] === element) { count++; } } return count; } console.log(myNames); // output your results 
0
source

All Articles