www.webdeveloper.com
Results 1 to 8 of 8

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

  1. #1
    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.

    Thanks for the advice.

  2. #2
    Join Date
    Oct 2010
    Location
    Versailles, France
    Posts
    1,268
    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
    alert(sortedWithoutDuplicatesArray)
    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. #3
    Join Date
    Feb 2012
    Location
    youTUBE
    Posts
    234
    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.
    Your answer will be 3,1,2.
    Last edited by WyCnet; 03-07-2013 at 12:16 PM.
    Knowledge is that which can be shown to be the case, and Intelligence is the method one uses to deploy the demonstration of what is the case, everything else is Information.

    For a stronger Text reading try:
    http://www.wyc3.com/diction.php

  4. #4
    Join Date
    Mar 2009
    Posts
    501
    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. #5
    Join Date
    Feb 2006
    Posts
    2,927
    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. #6
    Join Date
    Oct 2010
    Location
    Versailles, France
    Posts
    1,268
    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. #7
    Join Date
    Sep 2007
    Location
    istanbul
    Posts
    315
    Code:
      
    <script type="text/javascript">
    
    // http://www.webdeveloper.com/forum/showthread.php?274235-How-can-I-sort-an-array-by-how-many-times-a-data-is-in-the-array
    
    // 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
    
    Array.prototype.adedi=function(eleman){
    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])
    }
    alert(bulundu); // 3.1, 2.2, 4.3
    
    // dizideki elemanları büyükten küçüğe dizelim
    //http://www.w3schools.com/jsref/jsref_sort.asp
    
    bulundu.sort(function(a,b){return b-a});
    alert(bulundu);// 4.3, 3.1, 2.2 
    
    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];
    }
    alert(t); 
    /* 
    4 tane 3 var.
    3 tane 1 var.
    2 tane 2 var.
    */
    
    alert(dizi); // 3,1,2
    
    // This code worked in firefox 4.0b9 and Konqueror 4.5.5
    </script>
    Bismillahirrahmanirrahîm
    Hamd, Âlemlerin Rabbi, Rahmân, Rahîm, hesap ve ceza gününün (ahiret gününün) maliki Allah'a mahsustur. (Allahım!) Yalnız sana ibadet ederiz ve yalnız senden yardım dileriz. Bizi doğru yola, kendilerine nimet verdiklerinin yoluna ilet; gazaba uğrayanların ve sapıklarınkine değil.

  8. #8
    Join Date
    Sep 2007
    Location
    istanbul
    Posts
    315
    There was an error in the above code.

    Code:
      
    <script type="text/javascript">
    
    // http://www.webdeveloper.com/forum/showthread.php?274235-How-can-I-sort-an-array-by-how-many-times-a-data-is-in-the-array
    
    // 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
    
    Array.prototype.adedi=function(eleman){
    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++) {
    alert(A);
    el = A[0];
    bulundu[bulundu.length] = A.adedi(el) + "." + el;
    A = A.dizidenAt( el )
    if(A.length == 0) break;
    }
    alert("n =  "+n);
    alert(bulundu); // 1.1,1.2,2.3,1.5,3.6,1.9
    
    
    
    // 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});
    alert(bulundu); // 3.6,2.3,1.9,1.5,1.2,1.1
    
    
    
    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];
    }
    alert(t); 
    
    /* 
    3 tane 6 var. 
    2 tane 3 var. 
    1 tane 9 var. 
    1 tane 5 var. 
    1 tane 2 var. 
    1 tane 1 var. 
    */
    
    alert(dizi); // 6,3,9,5,2,1
    
    // 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.
    Bismillahirrahmanirrahîm
    Hamd, Âlemlerin Rabbi, Rahmân, Rahîm, hesap ve ceza gününün (ahiret gününün) maliki Allah'a mahsustur. (Allahım!) Yalnız sana ibadet ederiz ve yalnız senden yardım dileriz. Bizi doğru yola, kendilerine nimet verdiklerinin yoluna ilet; gazaba uğrayanların ve sapıklarınkine değil.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles