-3

I have this kind of array:

let mixedArr = ["Ship", "Ship", "Boat", "Ship", "Boat", "yacht" ]

I need a result that sorts the array by appearance, like this:

let sortedMixedArr = ["Ship", "Boat", "Yacht"]

Who can come up with a solution?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
falcon25
  • 11
  • 6

2 Answers2

0

You need to count items and then sort entries by count

let mixedArr = ["Ship", "Ship", "Boat", "Ship", "Boat", "yacht" ]

console.log(
  sortByCount(mixedArr)
)

function sortByCount(arr) {
  return [...arr.reduce((map, item) => {
    if(map.has(item)) {
      map.set(item, map.get(item) + 1) 
    } else {
      map.set(item, 1)
    }
    
    return map
  }, new Map).entries()] // create [[name, count]]
  .sort(([_, a], [__, b]) => b - a) // sort by count numerically
  .map(([name]) => name) // extract names
}
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
0

A shorter approach by using the keys of the map and sort them by the count.

var array = ["Ship", "Ship", "Boat", "Ship", "Boat", "Yacht"],
    map = array.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
    result = [...map.keys()].sort((a, b) => map.get(b) - map.get(a));

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thank you. This is what I was looking for - a more efficient way than in previous posts. (hence "efficient" in the headline) – falcon25 Jul 06 '19 at 17:16
  • @falcon25 It is not "more efficien way" than my answer. It does basically the same. Actually `sort` that makes overall algo to have `O(n*log(n))` complexity. Additional mapping does not affect the complexity. – Yury Tarabanko Jul 06 '19 at 18:36
  • Thank you Yury also obviusly, and yes I meant shorter code not time complexity. – falcon25 Jul 06 '19 at 19:24