【问题标题】:How can I append the content of one map to another map?如何将一张地图的内容附加到另一张地图?
【发布时间】:2010-11-07 05:37:40
【问题描述】:

我有以下两张地图:

map< string, list < string > > map1;
map< string, list < string > > map2;

我用以下内容填充了map1

1. kiran; c:\pf\kiran.mdf, c:\pf\kiran.ldf
2. test;  c:\pf\test.mdf, c:\pf\test.mdf

然后我将map1的内容复制到map2中,如下:

map2 = map1;

然后我再次用以下新内容填充map1

1. temp; c:\pf\test.mdf, c:\pf\test.ldf
2. model; c:\model\model.mdf, c:\pf\model.ldf

现在我必须将此内容附加到map2。我不能使用map2 = map1;,因为这会覆盖map2 中的现有内容。那么,我该怎么做呢?

【问题讨论】:

  • 根据文档,这似乎是正确的做法:http://www.cplusplus.com/reference/stl/map/operator=/
  • 你和用户Cute在几乎相同的时刻问非常相似的问题怎么会发生???
  • 好的,但是问两次这个问题有什么意义呢?你们中的一个人可以提出这个问题,然后你们两个都可以看到答案。重复问题只会削弱社区的努力,而且你得到的答案也不太好。
  • (我把这两个相同的问题合并了)

标签: c++ visual-c++ stl append stdmap


【解决方案1】:

您可以通过多种方式执行此操作,具体取决于您想要做什么:

  1. 使用复制构造函数:

    map< string, list < string > > map1;
    // fill in map1
    
    map< string, list < string > > map2(map1);
    
  2. 按照问题中的说明使用赋值运算符:

    map< string, list < string > > map1;
    map< string, list < string > > map2;
    
    // fill in map1
    
    map2 = map1;
    
  3. 全部手动完成:

    map< string, list < string > > map1;
    map< string, list < string > > map2;
    
    // fill in map1
    
    for (map< string, list < string > >::iterator i = map1.begin();
         i <= map1.end(); ++i) {
      map2[i.first()] = i.second();
    }
    

听起来 (1) 就是你想要的。

【讨论】:

  • 我想补充一点:std::copy(map1.begin(), map1.end(), insert_iterator(map2, map2.begin()) 是另一种方式
【解决方案2】:

您可以使用地图的插入方法。例如:

   std::map<int, int> map1;
    std::map<int, int> map2;

    map1[1] = 1;

    map2.insert(map1.begin(), map1.end());
    map1.clear();

    map1[2] =2;
    map2.insert(map1.begin(), map1.end());

【讨论】:

  • 这只是一个例子..它意味着键 val : 1 映射到值 1 :-)
【解决方案3】:
map<int,int> map1;
map<int,int> map2;
map1.insert(map2.begin(), map2.end());

这将从map2 的开头到结尾的元素插入map1。此方法是所有 STL 数据结构的标准方法,因此您甚至可以执行类似的操作

map<int,int> map1;
vector<pair<int,int>> vector1;
vector1.insert(map1.begin(), map1.end());

此外,指针也可以用作迭代器!

char str1[] = "Hello world";
string str2;
str2.insert(str1, str1+strlen(str1));

强烈推荐学习 STL 和迭代器的魔力!

【讨论】:

  • 记住两个&gt; &gt;之间的空格:)
  • 哦,是的,某些编译器会抱怨嵌套模板参数(cough GCC),因为 >> 看起来像一个流提取运算符。所以你可能需要在中间留一个空间。不过,我来自 Windows 世界,Visual Studio 中的编译器做了正确的事情。 :)
  • 在 C++1x 中,>> 之间的空格是不必要的。
  • 如果不需要 map2,请使用 std::make_move_iterator
【解决方案4】:

如果您想在定义时插入地图,这很好:

payload.insert({
            { "key1", "one" },
            { "key2", 2 },
        });

【讨论】:

    【解决方案5】:

    由于C++17 std::map 提供了merge() 成员函数。它允许您从一张地图中提取内容并将其插入到另一张地图中。基于您的数据的示例代码可以编写如下:

    using myMap = std::map<std::string, std::list<std::string>>;
    
    myMap  map2 = { {"kiran", {"c:\\pf\\kiran.mdf", "c:\\pf\\kiran.ldf"}},
                    {"test",  {"c:\\pf\\test.mdf",  "c:\\pf\\test.mdf"}} };
    
    myMap  map1 = { {"temp",  {"c:\\pf\\test.mdff",    "c:\\pf\\test.ldf"}},
                    {"model", {"c:\\model\\model.mdf", "c:\\pf\\model.ldf"}} };
    
    map2.merge(map1);
    
    for (auto const &kv : map2) {
        std::cout << kv.first << " ->";
        for (auto const &str : kv.second)
            std::cout << " " << str;
        std::cout << std::endl;
    }
    

    输出:

    kiran -> c:\pf\kiran.mdf c:\pf\kiran.ldf
    模型 -> c:\model\model.mdf c:\pf\model.ldf
    临时 -> c:\pf\test.mdff c:\pf\test.ldf
    测试 -> c:\pf\test.mdf c:\pf\test.mdf

    注意事项:

    • 一个键只能在一个映射中存在一次(例如,kirantesttempmodel 在您的示例中)。如果两个 map 包含相同的 key,则对应的元素不会合并到 map2 中,而是保留在 map1 中。
    • 如果所有元素都可以合并到map2 中,那么map1 将变为空。
    • merge() 函数非常有效,因为元素既不会被复制也不会被移动。相反,只有映射节点的内部指针被重定向。

    Code on Coliru

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-05
      • 2011-02-14
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多