How to swap map elements

11,225

Solution 1

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

Solution 2

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).

Solution 3

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

Solution 4

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"

Solution 5

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

wrongusername

Updated on June 08, 2022

Comments

  • wrongusername
    wrongusername almost 2 years

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