【问题标题】:Is there a way to copy non-conflicting map values using std::copy?有没有办法使用 std::copy 复制不冲突的地图值?
【发布时间】:2013-06-20 04:49:35
【问题描述】:

我正在寻找一种将值从一个映射复制到另一个映射的方法,类似于 this question,但我不希望冲突的值被第二个映射覆盖,我希望原始值保持不变。

例如,如果我有两张地图{a: 1, b: 2},我将{b: 3, c: 4} 复制到其中,第一张地图将被修改为{a: 1, b: 2, c: 4}

有没有办法使用标准库函数来做到这一点,还是我需要通过迭代手动完成并检查冲突值?

【问题讨论】:

  • 您可以使用std::copy_if,但对于您的想法,肯定有更好的方法...
  • @K-ballo “但无论你想到什么,肯定有更好的方法” - 是的,std::copy(没有_if)。跨度>

标签: c++ stl stdmap


【解决方案1】:

map.insert 有一个版本,它需要两个迭代器。如果项目(键)已存在于目标映射中,则插入失败,因此这正是您想要的。

#include <iostream>
#include <map>

int main() { 
    std::map<char, int> stuff;

    stuff['a'] = 1;
    stuff['b'] = 2;

    std::map<char, int> stuff2;

    stuff2['b'] = 3;
    stuff2['c'] = 4;

    stuff.insert(stuff2.begin(), stuff2.end());

    for (auto i : stuff)
        std::cout << i.first << "\t" << i.second << "\n";
}

结果:

a       1
b       2
c       4

【讨论】:

    【解决方案2】:

    您可以使用 std::for_each 和 lambda 来做到这一点:

    std::map<int, int> m1 = ...;
    std::map<int, int> m2 = ...;
    
    std::for_each(m2.begin(), m2.end(),
                 [&m1](const std::pair<const int, int>& a)
                 {
                     if(m1.find(a.first) == m1.end())
                        m1.insert(a);
                 });
    

    实际上,这只是将您必须手动执行的操作捆绑到 std::for_each 和 lambda 中。据我所知,没有比这更好的方式来实现您想要实现的目标。

    如果您的编译器支持emplace(GCC 4.7 不支持,但 4.8 支持),那么您可以使用它:

    std::for_each(m2.begin(), m2.end(),
                 [&m1](const std::pair<const int, int>& a)
                 {
                     m1.emplace(a.first, a.second);
                 });
    

    emplace 将保留元素,仅在前一个元素不存在时构造一个新元素。

    【讨论】:

    • “据我所知,没有比这更好的方式来实现你想要实现的目标了。” - 除了 Jerrystd::map::insert 解决方案,甚至还有一个更精简的&lt;algorithm> 解决方案,只需将其复制到地图中:std::copy(m2.begin(), m2.end(), std::inserter(m1, m1.end()));std::map::insert 自动保留现有密钥。
    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 2015-01-05
    • 2011-05-13
    • 2015-03-13
    相关资源
    最近更新 更多