# JavaScript Return sorted unique values from array, but if count is equal, return values in order

I am creating a function that takes in an array of unsorted integers and returns an array of the unique integers, sorted by frequency. However, if the integers have the same frequency, they will be returned in the original order of the input array. Here is my current function:

``````function uniqueUnionSorted(arr) {
counter = {};
for(var i=0; i<arr.length; i++) {
if (arr[i] in counter) {
counter[arr[i]] ++;
} else {
counter[arr[i]] = 1;
}
}
sortedStrings = Object.keys(counter).sort(function(a,b) {
return counter[b] - counter[a]
});
var sortedNumbers = sortedStrings.map(Number);
return sortedNumbers;
}
``````

So for an array like this:

``````arr = [1, 3, 2, 1, 5, 2, 1, 4]
``````

the function should return:

``````[1,2,3,5,4]
``````

However, my function is sorting the 5 and 4 and is returning:

``````[1,2,3,4,5]
``````

The cause of this reordering is that object properties that are numerical will come out ordered when using `Object.keys()`.

Instead of defining `counter` as an object, use a `Map`, which will retain the insertion order:

``````function uniqueUnionSorted(arr) {
var counter = new Map();
for(var i=0; i<arr.length; i++) {
counter.set(arr[i], (counter.get(arr[i]) || 0) + 1);
}
// Spreading the Map will produce an array of pairs
var sortedNumbers = [...counter].sort(function(a,b) {
return b[1] - a[1]; // sort by count
}).map(a => a[0]); // only keep the values, not the counts
return sortedNumbers; // Map keys retain original type, so they remain numeric
}

arr = [1, 3, 2, 1, 5, 2, 1, 4]

console.log(uniqueUnionSorted(arr));``````

In counter object we can also save lowest index of each element so we can keep elements with lower index earlier in sorted array.

``````function uniqueUnionSorted(arr) {
counter = {};
for(var i=0; i<arr.length; i++) {
if (arr[i] in counter) {
counter[arr[i]].count ++;
} else {
counter[arr[i]] = {'count' : 1, 'index' : i}; //save lowest index of element
}
}
sortedStrings = Object.keys(counter).sort(function(a,b) {
return counter[b].count - counter[a].count || counter[a].index - counter[b].index;
});
var sortedNumbers = sortedStrings.map(Number);
return sortedNumbers;
}

console.log(uniqueUnionSorted([1, 3, 2, 1, 5, 2, 1, 4]));``````

https://jsfiddle.net/anLrwwfa/4/

Here's another way you could do this using a Set object, an object to store frequency, and the original array to keep the origin intact. It's a bit longer than the current popular answer but I was in the midst of writing it, so I figured I would throw my hat in the ring.

``````function sortArr(arr) {
let uniqueValues = new Set();
let frequencies = new Object();

//get frequencies of values
for (let val of uniqueValues) {
frequencies[val] = 0;
}
arr.map((val) => frequencies[val]++);

//sort by frequency, then sort by original placement in array
let sorted_arr = Array.from(uniqueValues).sort((a, b) => {
return frequencies[a] - frequencies[b];
}).sort((a, b) => {
return (frequencies[a] === frequencies[b]) ?
Array.from(uniqueValues).indexOf(a) - Array.from(uniqueValues).indexOf(b) :
b;
});
//return array
return sorted_arr;
};

sortArr([1, 3, 2, 1, 5, 2, 1, 4]);  //1,2,3,5,4
``````

EDIT optimized code a bit

## typescript array sorting with random sort order

I want to sort an array based on an sort order. public array1: Array<string> = []; array.push(some string values); //E.g dog,apple,man I have a sort order like dog = 1 apple = 3 man = 2 So ...

I want to sort an array based on an sort order. public array1: Array<string> = []; array.push(some string values); //E.g dog,apple,man I have a sort order like dog = 1 apple = 3 man = 2 So ...

1. typescript array sorting
2. typescript array sorting string
3. typescript array sort by property
4. typescript array sort by date
5. typescript array sort alphabetically
6. typescript array sort descending
7. typescript array sort compare function
8. typescript array sort example
9. typescript array sort function
10. typescript array sort multiple fields
11. typescript array sort ascending
12. typescript array sort by key
13. typescript array sort not working
14. typescript array sort objects
15. typescript array sort by number
16. typescript array sort by value
17. typescript array sort desc
18. typescript array sort by field
19. typescript array sort by name
20. typescript array sort lambda

## google charts json date react

I've been trying to use Google charts with react. It works well, but I've moved the data from a local file to a mongoDB, which gives me a date-issue. With my test-data I added a correct data-format ...

I've been trying to use Google charts with react. It works well, but I've moved the data from a local file to a mongoDB, which gives me a date-issue. With my test-data I added a correct data-format ...

2. google charts json to datatable
6. google charts json data javascript
7. google charts json input example
9. google charts json data format
11. google charts json data source
16. google charts using json data

## Popover not hide when hovering over it

Currently i have the following structure <OverlayTrigger trigger={["hover", "focus", "click"]} placement="bottom" overlay={( <Popover className="timeline-popover-container" id="tpc-1"&...

Currently i have the following structure <OverlayTrigger trigger={["hover", "focus", "click"]} placement="bottom" overlay={( <Popover className="timeline-popover-container" id="tpc-1"&...

1. popover hide when click outside
2. popover hide on click
3. popover hide on body click
4. popover hide on blur
5. bootstrap popover hide when click outside
6. hide popover on mouse leave
7. hide popover on scroll
8. hide popover on button click
9. hide popover on mouse out
10. hide popover on click inside
11. popover on hide
12. hide popover on drag

## Make all inputs with class readOnly

So I am building a drag and drop form builder and I want to make a particular field on all the inputs readOnly. This can be Select Dropdown Text input Number input Date input Date input All these ...

So I am building a drag and drop form builder and I want to make a particular field on all the inputs readOnly. This can be Select Dropdown Text input Number input Date input Date input All these ...

1. make only inputs with type 'text'
2. make a sentence with inputs
1