6

I am new to Jquery and Javascript. Can someone please help me with Jquery sorting based on number of occurrence(count) in array. I tried various sorting methods but none of them worked.

I have an array in Javascript which is

allTypesArray = ["4", "4","2", "2", "2", "6", "2", "6", "6"]

// here  2 is printed four times, 6 is printed thrice, and 4 is printed twice

I need output like this

newTypesArray = ["2","6","4"]

I tried

function array_count_values(e) {
var t = {}, n = "",
    r = "";
var i = function (e) {
    var t = typeof e;
    t = t.toLowerCase();
    if (t === "object") {
        t = "array"
    }
    return t
};
var s = function (e) {
    switch (typeof e) {
    case "number":
        if (Math.floor(e) !== e) {
            return
        };
    case "string":
        if (e in this && this.hasOwnProperty(e)) {
            ++this[e]
        } else {
            this[e] = 1
        }
    }
};
r = i(e);
if (r === "array") {
    for (n in e) {
        if (e.hasOwnProperty(n)) {
            s.call(t, e[n])
        }
    }
}
return t
}
6: 3
}

output is {4: 2, 2: 6, 6:3}

7
  • 4
    Can you show us your code so far? Commented Feb 25, 2014 at 9:59
  • What were these various methods? How did they not work? Commented Feb 25, 2014 at 9:59
  • 1
    I hope the below post might help you to achieve the same.. stackoverflow.com/questions/19464440/… Commented Feb 25, 2014 at 10:00
  • That is not sorting (since you change the contents of the array) Commented Feb 25, 2014 at 10:06
  • @GabyakaG.Petrioli, Yes it's sorting by occurrence count for each element. Commented Feb 25, 2014 at 10:11

7 Answers 7

8

I don't think there's a direct solution in one step and of course it's not just a sort (a sort doesn't remove elements). A way to do this would be to build an intermediary map of objects to store the counts :

var allTypesArray = ["4", "4","2", "2", "2", "6", "2", "6", "6"];
var s = allTypesArray.reduce(function(m,v){
  m[v] = (m[v]||0)+1; return m;
}, {}); // builds {2: 4, 4: 2, 6: 3} 
var a = [];
for (k in s) a.push({k:k,n:s[k]});
// now we have [{"k":"2","n":4},{"k":"4","n":2},{"k":"6","n":3}] 
a.sort(function(a,b){ return b.n-a.n });
a = a.map(function(a) { return a.k });

Note that you don't need jQuery here. When you don't manipulate the DOM, you rarely need it.

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

2 Comments

FWIW you could save a couple chars return m[v] = ++m[v]||0, m
@elclanrs did it look like I was trying to golf ? ^^
7

Just adding my idea as well (a bit too late)

var allTypesArray = ["4", "4", "2", "2", "2", "6", "2", "6", "6"];
var map = allTypesArray.reduce(function(p, c) {
  p[c] = (p[c] || 0) + 1;
  return p;
}, {});

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

console.log(newTypesArray)

Comments

2

I don't think jquery is needed here.

There are several great answers to this question already, but I have found reliability to be an issue in some browsers (namely Safari 10 -- though there could be others).

A somewhat ugly, but seemingly reliable, way to solve this is as follows:

function uniqueCountPreserve(inputArray){
    //Sorts the input array by the number of time
    //each element appears (largest to smallest)

    //Count the number of times each item
    //in the array occurs and save the counts to an object
    var arrayItemCounts = {};
    for (var i in inputArray){
        if (!(arrayItemCounts.hasOwnProperty(inputArray[i]))){
            arrayItemCounts[inputArray[i]] = 1
        } else {
            arrayItemCounts[inputArray[i]] += 1
        }
    }

    //Sort the keys by value (smallest to largest)
    //please see Markus R's answer at: http://stackoverflow.com/a/16794116/4898004
    var keysByCount = Object.keys(arrayItemCounts).sort(function(a, b){
        return arrayItemCounts[a]-arrayItemCounts[b];
    });

    //Reverse the Array and Return
    return(keysByCount.reverse())
}

Test

uniqueCountPreserve(allTypesArray)
//["2", "6", "4"]

Comments

0

This is the function i use to do this kind of stuff:

function orderArr(obj){
    const tagsArr = Object.keys(obj)
    const countArr = Object.values(obj).sort((a,b)=> b-a)
  const orderedArr = []
  countArr.forEach((count)=>{
    tagsArr.forEach((tag)=>{
        if(obj[tag] == count && !orderedArr.includes(tag)){
        orderedArr.push(tag)
      }
    })
  })
  return orderedArr
}

Comments

0
const allTypesArray = ["4", "4","2", "2", "2", "6", "2", "6", "6"]

const singles = [...new Set(allTypesArray)]
const sortedSingles = singles.sort((a,b) => a - b)
console.log(sortedSingles)

Set objects are collections of values. A value in the Set may only occur once; it is unique in the Set's collection.

The singles variable spreads all of the unique values from allTypesArray using the Set object with the spread operator inside of an array.

The sortedSingles variable sorts the values of the singles array in ascending order by comparing the numbers.

1 Comment

the OP wants to sort based on the number each value appears in the original array.
0

Not sure if there's enough neat answers here, this is what I came up with:

Fill an object with counts for each of the elements:

let array = ['4', '4', '2', '2', '2', '6', '2', '6', '6'];
let arrayCounts = {}

for (j in array) arrayCounts[array[j]] ? arrayCounts[array[j]].count++ : arrayCounts[array[j]] = { val: array[j], count: 1 };

/* arrayCounts = {
  '2': { val: '2', count: 4 },
  '6': { val: '4', count: 2 },
  '4': { val: '6', count: 3 }
} */

For the values in that new object, sort them by .count, and map() them into a new array (with just the values):

let sortedArray = Object.values(arrayCounts).sort(function(a,b) { return b.count - a.count }).map(({ val }) => val);

/* sortedArray = [ '2', '6', '4' ] */

Altogether:

let arrayCounts = {}

for (j in array) arrayCounts[array[j]] ? arrayCounts[array[j]].count++ : arrayCounts[array[j]] = { val: array[j], count: 1 };
    
let sortedArray = Object.values(arrayCounts)
    .sort(function(a,b) { return b.count - a.count })
    .map(({ val }); => val);

Comments

0
var number = [22,44,55,11,33,99,77,88];

for (var i = 0;i<number.length;i++) {
  for (var j=0;j<number.length;j++){
    if (number[j]>number[j+1]) {
      var primary = number[j];
      number[j] =  number[j+1];
      number[j+1] = primary;
    }
  }
}
document.write(number);

2 Comments

Here are sorting an Array using 2 loops. First One is for showing output and the second one is for comparing values between arrays.
Your answer could be improved by adding more information on what the code does and how it helps the OP.

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.