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]

Please help!

Answer:1

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));
Answer:2

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]));
Answer:3

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();
//add values to set object
  arr.map((val) => uniqueValues.add(val));

//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

Answer:4

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

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 ...

  1. google charts json example
  2. google charts json to datatable
  3. google charts json format
  4. google charts json data
  5. google charts json
  6. google charts json data javascript
  7. google charts json input example
  8. google charts json file
  9. google charts json data format
  10. google charts json php
  11. google charts json data source
  12. google charts json date
  13. google charts json input
  14. google charts json datetime
  15. google charts json ajax
  16. google charts using json data
  17. google charts arraytodatatable json
  18. google charts load json
  19. google charts timeline json
  20. google charts api json

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

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