# Thread: How can I sort an array by how many times a data is in the array?

1. Registered User
Join Date
Mar 2013
Posts
1

## How can I sort an array by how many times a data is in the array?

I have an array with multiple numbers in it. I can't seem to figure out how to sort it base on the total amount a number is in the array. For example, my array has 1, 1, 1, 2, 2, 3, 3, 3, 3. I want to be able to sort it so it would look like 3, 1, 2. I also do not want to show duplicates.

2. Registered User
Join Date
Oct 2010
Location
Versailles, France
Posts
1,290
A one line script to sort and remove duplicates of an array :

Code:
```var anArray=[1,2,4,5,7,1,2,1,2,4,1,2,4,5,8];
var sortedWithoutDuplicatesArray=anArray.sort().join(',').replace(/([^,]+,)(?=\1)/g,'').split(',');
// Test
After sorting, we work on a string to remove all non-comma-character sub-string followed by a comma if the same sub-pattern is following (?=\1) an assertion (?= ) and a back reference \1

3. You are not sorting, you are counting. Given the data D1, you iterate through D1, and place a unique value of D1, into another array D2. If it is the first time you are placing a number into D2, place a count of 1 into another array D3, corresponding to the array index the number goes into D2. D2 can also be a 2 dimensional array pairing number and count. Subsequently if the number is already in D2, increment its count in D3. When you have examined all the numbers in D1, you have their unique counts in (D2,D3). Iterate through D3, looking for the largest number, second largest up to the smallest throughout D3.
Last edited by WyCnet; 03-07-2013 at 12:16 PM.

4. Registered User
Join Date
Mar 2009
Posts
590
I'm not totally sure I understand your requirements. The code below might meet them,
but understand that I have it written so that if two numbers have equal numbers of instances in the array, the number that is greatest will appear first in the final product rather than as it would appear in terms of "first noticed" in the array;

Also note that it returns an array with the finished product. It does not alter the array that is used as its argument.

Code:
```function strangeOp(arr){
var i, len, obj, used, b = []; a ={}, ret =[];
len = arr.length;
//set property 'key' as each unique value in arr--increment value if already there
for(i = 0; i < len; i++){
if(!a[arr[i]]){
a[arr[i]] = 1;
}
else{
a[arr[i]]++;
}
}
//change each key/value into a separate object and place in b array
for(i in a){
obj = {};
obj.num = (i * 1);  //make sure its used as a number, not a string
obj.quantity = a[i];
//console.log(obj.num + "   " + obj.quantity);
b.push(obj);
}
//not efficient, but short to write--do a bubble sort
len = b.length;
do{
used = false;
for(i = 0; i < (len - 1); i++){
if(b[i].quantity < (b[(i + 1)].quantity)){
obj = b[i]; b[i] = b[(i+1)]; b[(i + 1)] = obj;
used = true;
}
if(b[i].quantity == b[(i + 1)].quantity && b[i].num < b[(i+1)].num){
obj = b[i]; b[i] = b[(i+1)]; b[(i + 1)] = obj;
used = true;
}
}
}
while(used == true);
//record the data and send it back
for(i = 0; i < len; i++){
ret.push(b[i].num);
}

return ret;
}```

5. Registered User+
Join Date
Feb 2006
Posts
2,930
Most browsers implement the Array method .indexOf(what, i),
which returns the first index at which its value is found(starting at i, or 0 if not specified).
If the value is not found in the array, -1 is returned.

It is handy enough to include a 'shim' for it, if you must support the older
(IE8 and lower) browsers that lack it:

Code:
```if(!Array.prototype.indexOf){
Array.prototype.indexOf= function(what, i){
if(!i || typeof i!= 'number') i= 0;
var L= this.length;
while(i<L){
if(this[i]=== what) return i;
++i;
}
return -1;
}
}```

Your sort by frequency problem is now easy to implement-
with the array in hand, first get a unique set of values,
then sort them by comparing the frequency of each sorting pair.

Code:
```function sortByHiFreq(arr){
var unique= function(){
var i= 0, L= this.length, itm, A= [], n= 0;
while(i<L){
itm= this[i++];
if((itm || itm=== 0) && A.indexOf(itm)== -1) A[n++]= itm;
}
return A;
}
var freq= function(itm){
var count= 0, i=0;
while((i= this.indexOf(itm, i))!= -1){
++count;
++i;
}
return count;
}
return unique.call(arr).sort(function(a, b){
return freq.call(arr, b)- freq.call(arr, a);
});
// returns sorted by greatest frequency
}```

var A= [2, 5, 4, 1, 2, 2, 6, 4, 3, 1, 8, 1, 4, 6, 5, 2, 6, 3, 7, 8, 2, 5, 9, 9, 8];
sortByHiFreq(A)

/* returned value: (Array)
2,5,4,1,6,8,3,9,7
*/
Last edited by mrhoo; 03-07-2013 at 08:51 PM. Reason: simplified freq

6. Registered User
Join Date
Oct 2010
Location
Versailles, France
Posts
1,290
A variant for frequencies :
Code:
```var anArray=[1,2,4,5,7,1,2,1,2,4,1,2,4,5,8];

// Use of slice not to alter the original array
var toSortedStr=anArray.slice(0).sort().join(',');
var arrValues=toSortedStr.replace(/([^,]+,)(?=\1)/g,'').split(',');

// Sort by frequency
var frequency={}
var idx=arrValues.length;while (idx--) frequency[arrValues[idx]]=1;
toSortedStr.replace(/([^,]+),(?=\1)/g,function(all,subPattern){frequency[subPattern]++});

// To use alert with simple objects
Object.prototype.toString=function(){var i,c='';for (i in this) if (i.hasOwnProperty && !/function/.test(this[i])) c+='\nkey:'+i+' value:'+this[i];return c;}

// The result
alert('anArray :'+anArray+'\nArray values and frequencies : '+frequency)

// The script works too with
var anOtherArray="Jean,Paul,Jules,François,Jules,Louis,Jean,Pierre,Jules".split(',');```
We use replace with a function not to replace (without return value) but only to update the frequencies...
Last edited by 007Julien; 03-08-2013 at 06:22 AM.

7. Registered User
Join Date
Sep 2007
Posts
390
Code:
```
<script type="text/javascript">

// elemanı diziden çıkartıyor

Array.prototype.dizidenAt=function(eleman) {
var C= [];
for(var i = 0; i < this.length; i++) {
if(this[i] != eleman) { C[C.length] = this[i]; }
}
return C;
}

// dizide o elemandan kaç tane olduğunu sayıyor

var say = 0;
for(var i = 0; i < this.length; i++) {
if(this[i] == eleman) { say++;   }
}
return say;
}

var A = [1, 1, 1, 2, 2, 3, 3, 3, 3 ];
// önce bir rakamdan kaç tane var olduğunu yazalım, sonra nokta koyalım, sonra da o rakamı yazalım.

var bulundu = [];
for (n =0; n< A.length; n++) {
bulundu[bulundu.length] = A.adedi(A[n]) + "." + A[n];
A = A.dizidenAt(A[n])
}

// dizideki elemanları büyükten küçüğe dizelim
//http://www.w3schools.com/jsref/jsref_sort.asp

bulundu.sort(function(a,b){return b-a});

var dizi= [];
var t  = ""
var v;
for(var i=0; i<bulundu.length; i++) {
v = bulundu[i].split(".");
t +=  v[0]+ " tane " + v[1] + " var. \n";
dizi[dizi.length] = v[1];
}
/*
4 tane 3 var.
3 tane 1 var.
2 tane 2 var.
*/

// This code worked in firefox 4.0b9 and Konqueror 4.5.5
</script>```

8. Registered User
Join Date
Sep 2007
Posts
390
There was an error in the above code.

Code:
```
<script type="text/javascript">

// fonksiyona gönderilen elemanı diziye almayan ve yeni bir diziye dönen bir kod

Array.prototype.dizidenAt=function(eleman) {
var C = [];
for(var i = 0; i < this.length; i++) {
if(this[i] != eleman) { C[C.length]= this[i];  }

}

return C;
}

// fonksiyona gönderilen elemandan, dizide kaç tane olduğunu sayıyor

var say = 0;
for(var i = 0; i < this.length; i++) {
if(this[i] == eleman) { say++;   }
}
return say;
}

//var A = [1, 1, 1, 2, 2, 3, 3, 3, 3 ];
var A = [1, 2, 3, 3, 5, 6, 6, 6, 9 ];
// önce bir rakamdan kaç tane var olduğunu yazalım, sonra nokta koyalım, sonra da o rakamı yazalım.

var bulundu = [];
var el;
for (n =0; ; n++) {
el = A[0];
bulundu[bulundu.length] = A.adedi(el) + "." + el;
A = A.dizidenAt( el )
if(A.length == 0) break;
}

// Dizideki elemanları büyükten küçüğe dizelim. En çok bulunandan en az bulunana doğru dizeceğim.
//http://www.w3schools.com/jsref/jsref_sort.asp

bulundu.sort(function(a,b){return b-a});

var dizi= [];
var t  = ""
var v;
for(var i=0; i<bulundu.length; i++) {
v = bulundu[i].split(".");
t +=  v[0]+ " tane " + v[1] + " var. \n";
dizi[dizi.length] = v[1];
}

/*
3 tane 6 var.
2 tane 3 var.
1 tane 9 var.
1 tane 5 var.
1 tane 2 var.
1 tane 1 var.
*/

// This code worked in firefox 4.0b9 and Konqueror 4.5.5
</script>```
Last edited by Ayşe; 03-11-2013 at 04:34 AM.