Vitalii Maslianok
Vitalii Maslianok

Reputation: 1631

JavaScript sort Array by uniqueness

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"]

Upvotes: 0

Views: 152

Answers (6)

Alberto De Caro
Alberto De Caro

Reputation: 5213

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});
    

Upvotes: 1

ZER0
ZER0

Reputation: 25322

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.

Upvotes: 2

guessimtoolate
guessimtoolate

Reputation: 8642

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"

Upvotes: 1

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67207

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);

Upvotes: 1

Aamir Shah
Aamir Shah

Reputation: 646

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

Upvotes: 1

bniwredyc
bniwredyc

Reputation: 8829

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];
});

Upvotes: 1

Related Questions