0

I have input array as follows. I want to get the unique occurrences name and frequency of those occurrences. I am able to achieve that as shown below.

let input = ["apple", "orange" , "pear", "orange", "apple", "orange"];
input.reduce(function (acc, curr) {
  return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});

Result:

{ "apple": 2, "orange": 3, "pear": 1}

But I am expecting the result to be in ascending order of frequencies as shown below. Can someone let me know how to achieve it. Also, I have used function above. Can someone let me know how to use it with arrow operator (ES8 feature)

Expected Result:

{ "orange": 3, "apple": 2, "pear": 1 }
dippas
  • 58,591
  • 15
  • 114
  • 126
Aren Trot
  • 283
  • 3
  • 13
  • 1
    object properties order is not guaranteed. use a Map if order is required? – cmgchess Jul 19 '22 at 17:13
  • can you pls share how to use it with a Map ? – Aren Trot Jul 19 '22 at 17:26
  • any reason why it has to sorted. and if why not have a sorted array instead of an object. `const sorted = new Map(Object.entries(output).sort((a,b) => b[1]-a[1]))` – cmgchess Jul 19 '22 at 17:48
  • Does this answer your question? [Sorting object property by values](https://stackoverflow.com/questions/1069666/sorting-object-property-by-values) – Heretic Monkey Jul 19 '22 at 17:56
  • There's no such thing as "ES8"; it's called "ES2017" or ECMAScript 2017. – Heretic Monkey Jul 19 '22 at 17:58
  • @HereticMonkey i also saw this but is the order guaranteed in object even after all the transformations. also i didnt find a single answer that uses Map. wondering if its a valid usecase – cmgchess Jul 19 '22 at 18:06
  • 1
    @cmgchess The order is "guaranteed" in that the order is guaranteed to be insertion order. Since `fromEntries` runs in whatever order the array is iterated in, it should be in the correct order. But honestly, the OP should be getting the data via `Object.entries` and sorting it when using the data, but that's, like, my opinion, man. – Heretic Monkey Jul 19 '22 at 18:54

1 Answers1

1

You can convert the unsorted object, which is not sortable, to an array, which is sortable, and then back to an object:

let input = ["apple", "orange" , "pear", "orange", "apple", "orange"];
const unsorted = input.reduce(function (acc, curr) {
  return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});

const sorted = Object.entries(unsorted) // converts to array of key/value pairs
    .sort(([,a],[,b]) => b - a) // sort descending (switch a and b to sort in reverse order)
    .reduce((r, [k, v]) => ({ ...r, [k]: v }), {}); // reduce back to object
console.log(sorted)
anqit
  • 780
  • 3
  • 12