wrongusername
wrongusername

Reputation: 18918

How to swap map elements

In C++, how would I swap two elements of a map?

Upvotes: 4

Views: 14112

Answers (6)

hhafez
hhafez

Reputation: 39750

What do you mean by swap in a map? A normal plain vanila map doesn't have any particular order so speaking of swapping has no meaning in reference to order.

If you are looking for C++ map implementation that preserves order, in which case ordering becomes meaningful then look here

If however you are looking to swap the value associated with one key with the value associated with a second key then just do

map<char, string> myMap;

myMap['a'] = "firstValue";
myMap['b'] = "secondValue";

/* Now let's swap */
string tmpString = myMap['a'];
myMap['a'] = myMap['b'];
myMap['b'] = tmpString

Upvotes: 0

Oleksandr Kozlov
Oleksandr Kozlov

Reputation: 802

  auto mymap = std::map<int, char>{{1, 'a'}, {2, 'b'}};
  std::swap(mymap.at(1), mymap.at(2));

Upvotes: 2

Animiral
Animiral

Reputation: 31

None of the answers provided so far deal with nonexistant keys and preserving the nonexistance of these keys.

template<class Key, class Value>
void swap_map_elements(std::map<Key, Value>& map, const Key& key1, const Key& key2)
{
    auto it1 = map.find(key1);
    auto it2 = map.find(key2);
    auto end = map.end();

    if(it1 != end && it2 != end) {
        std::swap(it1->second, it2->second);
    }
    else if(it1 != end) {
        map.emplace(std::make_pair(key2, std::move(it1->second)));
        map.erase(key1);
    }
    else if(it2 != end) {
        map.emplace(std::make_pair(key1, std::move(it2->second)));
        map.erase(key2);
    }
}

Example:

auto M = std::map<int, std::string>();
M.emplace(std::make_pair(1, "one"));
M.emplace(std::make_pair(2, "two"));

swap_map_elements(M, 1, 2); // 1: "two", 2: "one"
swap_map_elements(M, 1, 4); // 2: "one", 4: "two"
swap_map_elements(M, 5, 2); // 4: "two", 5: "one"
swap_map_elements(M, 8, 9); // 4: "two", 5: "one"

Upvotes: 3

icecrime
icecrime

Reputation: 76755

The provided answers are correct but are using operator[] twice for the same keys, which isn't free and could be avoided :

std::map<char, std::string> a;

Solution 1 :

std::string &item1 = a['a'];
std::string &item2 = a['b'];
std::swap(item1, item2);

Solution 2 :

const std::map<char, std::string>::iterator item1 = a.find('a');
const std::map<char, std::string>::iterator item2 = a.find('b');
if ((item1 != a.end()) && (item2 != a.end()))
    std::swap(item1->second, item2->second);

Of course, the two solutions aren't equivalent (solution 2 only swaps values which are already in the map, solution 1 inserts without questioning and might end up swapping two default constructed strings).

Upvotes: 7

Kylo
Kylo

Reputation: 2320

I think std::swap() is a good choice.

Upvotes: 3

Draco Ater
Draco Ater

Reputation: 21226

Do you mean this?

const T tmp = map["a"];
map["a"] = map["b"];
map["b"] = tmp;

Upvotes: 0

Related Questions