The sort function can take a comparison function, in which you can just compare the number of repetitions, and not fix elements.
In addition, since non-numeric keys are added to the array, you can do without the second array:
for (var len = arr.length, i = len; --i >= 0;) { if (arr[arr[i]]) { arr[arr[i]] += 1; arr.splice(i, 1); } else { arr[arr[i]] = 1; } }
Since the added properties are not numeric, they are not involved in sorting, but they can be accessed in the comparison function:
arr.sort(function(a, b) { return arr[b] - arr[a]; });
For output, you can use several ways: for example, get a new array with elements in which there will be fields corresponding to both the element and the number of its repetitions. Or use the JSON.stringify function
Example:
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s"]; for (var len = arr.length, i = len; --i >= 0;) { if (arr[arr[i]]) { arr[arr[i]] += 1; arr.splice(i, 1); } else { arr[arr[i]] = 1; } } arr.sort(function(a, b) { return arr[b] - arr[a]; }); console.log(arr); var stringResult = JSON.stringify(arr, function(k, v) { if (k == '') return v; return `${v} - ${arr[v]}`; }, 2); document.getElementById('result').innerHTML = stringResult; console.log(stringResult); console.log(arr.map((el, i, a) => ({ [el]: a[el] })));
<pre id="result"></pre>
In order not to work with an array as with objects, you can use the reduce function and immediately get an array that can be sorted.
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s", "s", "s"]; var resultReduce = arr.reduce(function(acc, cur) { if (!acc.hash[cur]) { acc.hash[cur] = { [cur]: 1 }; acc.map.set(acc.hash[cur], 1); acc.result.push(acc.hash[cur]); } else { acc.hash[cur][cur] += 1; acc.map.set(acc.hash[cur], acc.hash[cur][cur]); } return acc; }, { hash: {}, map: new Map(), result: [] }); var result = resultReduce.result.sort(function(a, b) { return resultReduce.map.get(b) - resultReduce.map.get(a); }); console.log(result);