【问题标题】:How to transfer keys and values ​from map to another map?如何将键和值从地图转移到另一个地图?
【发布时间】:2020-01-23 05:29:37
【问题描述】:

我想将键和值转移到另一个地图,但同时留下旧的键和值。

我该怎么做? 我的例子不起作用。

    map1.emplace(1, 1001);
    map1.emplace(2, 1002);
    map1.emplace(3, 1003);

    map2.emplace(10, 1010);
    map2.emplace(11, 1011);
    map2.emplace(12, 1012);

    map1 = map2;

    cout << map1[1] << endl;
    cout << map1[10] << endl;
    cout << map2[3] << endl;

【问题讨论】:

  • 跟即将到来的C++20有什么关系?
  • “不起作用”是什么意思?发生什么了?什么是预期的输出?实际输出是多少?请花一些时间阅读有关how to ask good questionsthis question checklist 的信息。
  • 也许您应该花点时间阅读更多关于std::map 及其assignment operator 的信息(尤其是它说“替换容器的内容”的部分。 (强调我的))。
  • 您可能也有兴趣阅读std::copystd::insert_iterator,它们可以帮助您将值从一张地图复制到另一张地图。
  • std::copy(map2.begin(), map2.end(), std::inserter(map1, map1.end())); ,假设您事先设置了适当的包含,可能您正在尝试做。

标签: c++ c++20


【解决方案1】:

实际上,当您将map2 分配给map1 时。它将map2 复制到map1 中,替换旧内容。

因此,赋值后,旧值丢失,map1 现在是map2 的精确副本。

如果您只想添加新元素,您可以改用insert() 函数。这可能如下所示:

#include <map>

int main()
{
    std::map<int, int> map1 {{1 ,1001}, {2, 1002}, {3, 1003}};
    std::map<int, int> map2 {{10, 1010}, {11, 1011}, {12, 1012}};

    map1.insert(map2.cbegin(), map2.cend());

    for(const auto & e : map1)
    {
        std::cout << e.first << ": " << e.second << std::endl;
    }

    return 0;
}

这样,map2 被插入到map1 中,而不会删除旧内容。你只需要知道,如果你尝试插入一个已经存在的键,它不会被插入(因为每个元素在std::map 中都是唯一的)。


编辑:

如果你也想替换已经存在的值,你可以简单地使用operator[]。它可能看起来像:

for(const auto & e : map2)
{
    // If the key exists, change only the value, add the {key, value} otherwise
    map1[e.first] = e.second;
}

【讨论】:

  • 如果key相同怎么替换?
  • @Skype 我已经进行了编辑,以便为您提供一个简单的解决方案。
  • 对于 c++17 及更高版本,insert_or_assign() 是另一种选择(因为它不需要映射类型是默认可构造的)。
【解决方案2】:

您可以将std::insert map2 转换为map1。如果一个键存在于map1 中,它将保持其值(不管这个键可能在map2 中)。如果map2 中存在键但map1 中不存在键,则会将其值复制到map1

#include <iostream>
#include <map>

enum { ONLY_IN_MAP1, BOTH_IN_MAP1_AND_MAP2, ONLY_IN_MAP2 };

int main()
{
    std::map<int, int> map1, map2;

    map1.emplace(ONLY_IN_MAP1, 1);
    map1.emplace(BOTH_IN_MAP1_AND_MAP2, 2);

    map2.emplace(ONLY_IN_MAP2, 3);
    map2.emplace(BOTH_IN_MAP1_AND_MAP2, 4);

    map1.insert(cbegin(map2), cend(map2));

    std::cout << map1[ONLY_IN_MAP1]          << '\n'; // 1
    std::cout << map1[BOTH_IN_MAP1_AND_MAP2] << '\n'; // 2
    std::cout << map1[ONLY_IN_MAP2]          << '\n'; // 3
}

演示:https://coliru.stacked-crooked.com/a/571c588e8cee5fb8

【讨论】:

  • cbegin from begincend from end map1.insert(map2.begin(), map2.end()); map1.insert(cbegin(map2), cend(map2)); 有什么区别
  • 如果key相同怎么替换?
  • @Skype 问一个更精确的问题,你会得到更精确的答案。
  • @Skype cbegin()cend()const 迭代器,分别指向容器的开头和结尾。不同的是不能修改const迭代器指向的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多