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"]
2
  • Are all items strings? Commented Apr 6, 2013 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: stackoverflow.com/q/5667888/218196. Commented Apr 6, 2013 at 10:35

6 Answers 6

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.

Sign up to request clarification or add additional context in comments.

1 Comment

It's amazing how you convert an array to frequency object. Thanks!
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];
});

Comments

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

Comments

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

Comments

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"

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.