sort an unordered_map using sort()

54,972

This is impossible from both a compilation and logical standpoint. From a type standpoint, std::sort requires:

-RandomIt must meet the requirements of ValueSwappable and RandomAccessIterator.
-The type of dereferenced RandomIt must meet the requirements of MoveAssignable and MoveConstructible.

The iterator type on std::unordered_map is a ForwardIterator, not a RandomAccessIterator, so the first requirement is unsatisfied. The type of the dereferenced iterator is pair<const Key, T>, which is not MoveAssignable (can't assign to const), so the second requirement is also unsatisfied.

From a logical standpoint, sorting an unordered container makes no sense. It's unordered. And the complexity guarantees that unordered_map is able to achieve require a very specific ordering that you shouldn't be, and aren't, allowed to mess with.

If you want to "sort" your unordered_map, put them in a vector:

std::vector<std::pair<char, int>> elems(table.begin(), table.end());
std::sort(elems.begin(), elems.end(), comp);
Share:
54,972

Related videos on Youtube

pratiksaha
Author by

pratiksaha

Updated on July 09, 2022

Comments

  • pratiksaha
    pratiksaha almost 2 years

    I am trying to sort an unordered_map using sort() function but I keep getting a compiler error. Can anyone help?

    bool comp(pair<char,int> a, pair<char,int> b) {
        return a.second < b.second;
    }
    
    void rearrangeKDist(char str[], int d) {
        int n = strlen(str);
        unordered_map<char, int> table;
        for (int i=0; i<n; i++) {
            unordered_map<char, int>::iterator it = table.find(str[i]);   
            if (it == table.end()) {
                table.insert(make_pair(str[i], 1));
            } else {
                it->second = it->second+1;
            }
        }
        for (unordered_map<char, int>::iterator it=table.begin(); it!=table.end(); it++)
            cout<<it->first<<" "<<it->second<<endl;
        sort(table.begin(), table.end(), comp);
        for (unordered_map<char, int>::iterator it=table.begin(); it!=table.end(); it++)
            cout<<it->first<<" "<<it->second<<endl;
    
    }
    
    • Borgleader
      Borgleader almost 9 years
      Why do you want to sort an unordered map? If you need the data to be sorted, use a regular map. (P.S: You wont be able to sort it in-place. It would break the invariants of the map)
    • Barry
      Barry almost 9 years
      Side-node, instead of the find/insert/increment... you could just do ++table[str[i]];
    • Tony Delroy
      Tony Delroy almost 9 years
      Possible duplicate / my explanation here
  • Nejc Galof
    Nejc Galof almost 7 years
    For std::sort we need: #include <algorithm>
  • Jason
    Jason almost 6 years
    Hi thanks for the answer, I really like the way of the first reason to explain that. I am in the transit from novice to intermedia, could you give some suggestion on what kind of resources to look at such that we could explain issues in a more solid way like you did here?@Barry