0

I have an array of items. For example:

var classes = ['link', 'block', 'hide', 'link', 'menu', 'block', 'content', 'link', 'footer', 'img', 'img', 'link', 'modal', 'button', 'form', 'input', 'button', 'input', 'link', 'toString', 'valueOf', 'button'];

I need to get an array of unique items, sorted by frequency:

'link' item should be in the first place, because array contain it 5 times.

'button' item should be in the second place, because array contain it 3 times.

etc

["link", "button", "input", "img", "block", "footer", "content", "modal", "menu", "form", "hide", "toString", "valueOf"]
Vitalii Maslianok
  • 1,601
  • 1
  • 14
  • 16
  • Are all items strings? – kennytm Apr 06 '13 at 10:33
  • 1
    Which part are you having problems with? Please post the code you have so far. Here for example is a related question about how to count the unique elements of an array: http://stackoverflow.com/q/5667888/218196. – Felix Kling Apr 06 '13 at 10:35

6 Answers6

2

You can obtain it easily using ECMAScript 5 methods:

var classes = ['link', 'block', 'hide', 'link', 'menu', 'block', 'content', 'link', 'footer', 'img', 'img', 'link', 'modal', 'button', 'form', 'input', 'button', 'input', 'link', 'toString', 'valueOf', 'button'];

var frequency = classes.reduce(function(data, item) {
    data[item] = -~data[item];
    return data;
}, {});

var uniques = Object.keys(frequency).sort(function(a, b) {
    return frequency[b] - frequency[a];
});

console.log(uniques);

If you have to support old browsers, you can still use the shims.

ZER0
  • 24,846
  • 5
  • 51
  • 54
1

Two steps:

  1. arrange your data in an array of {'item', 'frequency'} couples
  2. use the array.sort function:

    var arr = [{'item':'link', 'freq':4},{'item':'button', 'freq':2},{'item':'div', 'freq':5}];
    
    arr.sort(function(a,b){return b.freq - a.freq});
    
GitaarLAB
  • 14,536
  • 11
  • 60
  • 80
Alberto De Caro
  • 5,147
  • 9
  • 47
  • 73
1

Underscore.js solution:

var dict = _.reduce(classes, function(memo, class) {
    memo[class] = memo[class] ? memo[class] + 1 : 1
}, {});

var pairs = _.pairs(dict);

var sortedPairs = _.sort(pairs, function(pair) {
    return pair[1];
});

var result = _.map(sortedPairs, function(pair) {
    return pair[0];
});
bniwredyc
  • 8,649
  • 1
  • 39
  • 52
1

It should have to be something like this.

        var classes = [ 'link', 'block', 'hide',
                    'link', 'menu', 'block',
                    'content', 'link', 'footer',
                    'img', 'img', 'link', 'modal',
                    'button', 'form', 'input',
                    'button', 'input', 'link',
                    'toString', 'valueOf', 'button'];
    var counter;
    var i=0,z=0,x=0;
    var bool = false;
    while(!bool){
        for(j=1;j<classes.length;j++)
        {
            if(( classes[i] == -1) || (classes[j] == -1))
            {
                i++;j++;
            }
            else if(classes[i] === classes[j])
            {
                classes[j] = -1;
                counter = z + "," + (Number(x)+1);
            }
            x++;
        }
        i++;
        z++;
        if((classes.length-1) == i)
        {
            bool = true;
        }
    }

In the End count the 2nd variable in the counter (z , "x") so at every
instance Z the occurance will be x

Aamir Shah
  • 646
  • 5
  • 14
1

Try this out,

var xArray= ["apple","cake","pie","pie","pie","apple"];
var xNew=[];
var temp;

for(var i=0;i<=xArray.length-1;i++)
{
   if( xNew.indexOf(xArray[i]) === -1 )
   {
   xNew.push(xArray[i])    
   }
}

function occuranceOf(xStr)
{
    var xCount =0;
    for(var i=0; i<=xArray.length-1; i++)
    {
        if(xArray[i] === xStr)
            {
        xCount += 1;        
            }                 
    }

    return xCount;
}

for(var i=0;i<=xNew.length-1;i++)
{
    for(var j=i+1; j<=xNew.length-1; j++)
    {
        if(occuranceOf(xNew[i]) < occuranceOf(xNew[j]))
        {
            temp = xNew[i];
            xNew[i] = xNew[j];
            xNew[j] = temp;
        }
    }
}

alert(xNew);
Rajaprabhu Aravindasamy
  • 66,513
  • 17
  • 101
  • 130
1

how about:

var classes = ['link', 'block', 'hide', 'link', 'menu', 'block', 'content', 'link', 'footer', 'img', 'img', 'link', 'modal', 'button', 'form', 'input', 'button', 'input', 'link', 'toString', 'valueOf', 'button'],
    frequency = {},
    sortedClasses = [],
    result = [];

for (var i in classes) {
    var name = 'z' + classes[i];
    frequency[name] = frequency[name] ? frequency[name] + 1 : 1;
}

for (var j in frequency) {
    sortedClasses.push([j, frequency[j]]); 
}

sortedClasses.sort(function (a, b) {
    return b[1] - a[1]; 
});

for (var g in sortedClasses) {
    var name = sortedClasses[g][0].substr(1);
    result.push(name);
}

I prefixed classes with "z" because of their names eg. "valueOf"

guessimtoolate
  • 8,372
  • 2
  • 18
  • 26