user12897373
user12897373

Reputation:

Is there any C++ function to sort a Map?

I want to know that how can I sort an ordered_map in C++ on the basis of values. Is there any function to do it?

Upvotes: 2

Views: 2251

Answers (5)

rustyx
rustyx

Reputation: 85371

A map is an associative container. Unlike sequential containers, where you have control over the location of the element, an associative container itself controls the order of the elements. Once the associative container is created, the ordering cannot be changed.

There is no ordered_map in standard C++. There is std::map, which is a tree (and therefore the elements already appear sorted based on the comparator) and std::unordered_map, which is a hash table (the elements are somewhat ordered based on the hash of the key).

Upvotes: 3

mfnx
mfnx

Reputation: 3018

No. A std::map is designed to store elements formed by a combination of a key value and a mapped value, where the key values are used to sort and identify the elements.

To sort by values, you could simply create an inverted map:

template <typename T1, typename T2>
std::map<T2, T1> invert(const std::map<T1, T2> & m)
{
    std::map<T2, T1> ret;
    for (const auto& e : m)
        ret[e.second] = e.first;
    return ret;
}

There are many solutions to this problem, and you might prefer one over the other in function of your needs.

Upvotes: 0

Pikachu
Pikachu

Reputation: 314

You can not really change the elements of a std::map. However, you can use std::vector to first copy the elements in the vector and then use std::sort(). Sort elements of std::map.

#include<iostream>
#include <map>
#include <vector>
#include <algorithm>

typedef std::pair<std::string,int> pair;

int main()
{
    // input map
    std::map<std::string,int> map = {
        {"two", 2}, {"one", 1}, {"four", 4}, {"three", 3}
    };

    // create an empty vector of pairs
    std::vector<pair> vec;

    // copy key-value pairs from the map to the vector
    std::copy(map.begin(),
            map.end(),
            std::back_inserter<std::vector<pair>>(vec));

    // sort the vector by increasing order of its pair's second value
    // if second value are equal, order by the pair's first value
    std::sort(vec.begin(), vec.end(),
            [](const pair& l, const pair& r) {
                if (l.second != r.second)
                    return l.second < r.second;

                return l.first < r.first;
            });

    // print the vector
    for (auto const &pair: vec) {
        std::cout << '{' << pair.first << "," << pair.second << '}' << '\n';
    }

    return 0;
}

Upvotes: 1

Timo
Timo

Reputation: 9835

This answer covers the case that you are referring to values inside the map itself.

First off, the container you want is std::map. There is no ordered_map in the standard library, only map or unordered_map.

You can supply map with your own comparer so that it sorts it like you want. For example:

struct MyOrder
{
    constexpr bool operator()(MyType a, MyType b) const 
    {
        // return true, so that a < b accodring to your definition
    }
};

and use it like

std::map<MyType, MyOrder> myMap;

Upvotes: 1

Jarod42
Jarod42

Reputation: 217398

You cannot rearrange elements of (ordered_)map(/set).

You might copy values (and/or keys) into std::vector and std::sort that.

Upvotes: 0

Related Questions