2

Array:

5, 5, 5, 9, 4, 2, 2, 2, 2, 2, 3, 3, 3, 3

Ideal Output:

2, 3, 5, 9, 4

PHP made this easy with array_count_values() and arsort(), but javascript is proving a little tougher. Any help?


Also, what about returning it containing the counts as well? For future needs

GameDevGuru
  • 1,095
  • 2
  • 12
  • 27

1 Answers1

4

Count unique entries, create an array of uniques, then sort based upon counts

function count(arr) { // count occurances
    var o = {}, i;
    for (i = 0; i < arr.length; ++i) {
        if (o[arr[i]]) ++o[arr[i]];
        else o[arr[i]] = 1;
    }
    return o;
}

function weight(arr_in) { // unique sorted by num occurances
    var o = count(arr_in),
        arr = [], i;
    for (i in o) arr.push(+i); // fast unique only
    arr.sort(function (a, b) {
        return o[a] < o[b];
    });
    return arr;
}

weight([1, 3, 3, 5, 5, 5, 2, 2, 2, 2]);
// one 1, two 3s, three 5s, four 2s
// [2, 5, 3, 1]

You example has both one 9 and one 4, so if you want the order defined, more work would be necessary. Otherwise;

weight([5, 5, 5, 9, 4, 2, 2, 2, 2, 2, 3, 3, 3, 3]);
// [2, 3, 5, 4, 9]

To produce an Array of Objects

function weight(arr_in) { // unique sorted by num occurances
    var o = count(arr_in),
        arr = [], i;
    for (i in o) arr.push({value: +i, weight: o[i]}); // fast unique only
    arr.sort(function (a, b) {
        return a.weight < b.weight;
    });
    return arr;
}

var result = weight([5, 5, 5, 9, 4, 2, 2, 2, 2, 2, 3, 3, 3, 3]);
/* [
    {"value": 2, "weight": 5},
    {"value": 3, "weight": 4},
    {"value": 5, "weight": 3},
    {"value": 4, "weight": 1},
    {"value": 9, "weight": 1}
] */

Now, to get the value at index i, you do result[i].value, and for it's weighting result[i].weight.

Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Could i also get output with count of each value? For future reference. – GameDevGuru Aug 02 '13 at 02:08
  • No i mean `2:5, 3:4, 5:3, 9:1, 4:1` – GameDevGuru Aug 02 '13 at 02:25
  • I've spent hours trying, but I can't seem to modify it properly. – GameDevGuru Aug 02 '13 at 14:20
  • You-re not being very clear - `2:5, 3:4, 5:3, 9:1, 4:1` does not make sense; do you mean the _Object_ `{2: 5, 3: 4, 4: 1, 5: 3, 9: 1}`? This is what is `return`ed by `count`. Alternatively, perhaps you want an _Array_ of _Objects_ like `[{value: 2, weight: 5}, {value: 3, weight: 4}/*, etc*/]` with which you would always thereafter need to specify whether you wanted the value or the weight. In my opinion using the _Object_ is easier as you can have it as a dictionary lookup if you ever wanted and does not require more code :) – Paul S. Aug 02 '13 at 16:09
  • Yea i would like it as a sorted array of objects so it's easier to iterate through. I come from PHP so i'm having a little trouble with this. – GameDevGuru Aug 03 '13 at 06:18
  • Count is working properly, it just wont sort by the count. I've tried everything! – GameDevGuru Aug 03 '13 at 15:56
  • The integers have various lengths. `eg: 333223, 2333,23444455` etc I believe that's making a difference for sort – GameDevGuru Aug 03 '13 at 16:11
  • I fixed it. `return b.weight - a.weight;` – GameDevGuru Aug 03 '13 at 20:38