将一个地图的内容附加并替换为另一个地图

Append and replace the contents of one map to another map?

本文关键字:地图 替换 另一个 一个      更新时间:2023-10-16

所以我知道 map1.insert(map2.begin(), map2.end());将插入 map2的所有元素中 map1

但是map2中可能存在一些元素,而map1中已经存在。这些元素将不会更新。

e.g. map1 has { 3 : 4, 6 : 7 }
     map2 has { 11: 5, 6 : 0 }
     Now if I do map1.insert(map2.begin(), map2.end()), I will get
     map1 = { 3: 4, 6 : 7, 11 : 5 }
     But what I want is
     map1 = { 3: 4, 6 : 0, 11 : 5 }

我想知道是否有诸如map1.insert(map2.begin(), map2.end());这样的功能,它会迫使已经存在的密钥更新?

更新:我知道可以使用以下操作:map1[k] = v对于所有密钥,MAP2中的值对。

但是是否有任何可以这样做的函数?

在C 17中,然后合并交换。

map2.merge(map1);
map2.swap(map1);

与基于插入的变体相比,它的好处是它只是拼接节点。没有分配,没有作业,没有施工。

您可以做相反的事情,然后交换。

map2.insert(map1.begin(), map1.end()); std::swap(map1, map2);

template<typename MapT>
void join_inplace(MapT& m1, MapT const& m2)
{
    for (auto p : m2)
        m1[p.first] = p.second;
}

ideone

编辑

您不在乎map2

template<typename MapT>
void join_inplace(MapT& target, MapT& other)
{
    for (auto& p : other)
        target[std::move(p.first)] = p.second;
}

由于您不在乎map2的状态,因此您可以移动其元素

template<typename MapT>
void join_inplace(MapT& map1, MapT &&map2)
{
  for(auto& p : map2)
    map1.insert_or_assign(std::move(p.first), std::move(p.second));
  map2.clear();
}

不需要映射类型的默认类型可构造(与基于map::operator[]的解决方案不同(。

这是一个C 17解决方案,避免了任何分配,副本或移动(密钥和映射类型的(

template<typename MapT>
void join_inplace(MapT&map1, MapT&&map2)
{
  for(auto it=map1.begin(), end=map1.end(); it!=end;)
    map2.insert(std::move(map1.extract(it++)));
  std::swap(map1,map2);
}

解释。

  1. map::extract(it)提取一个节点,从而使迭代器it无效。因此,我们必须通过map1.extract(it++)而不是像往常一样在for循环中通过CC_15进行迭代。
  2. map::insert(node_type&&)插入节点 iff 键尚不知道。
  3. 否则节点被破坏
  4. 最后,我们必须交换地图(根据Valentindavid的答案(。

注意。正是在我写这个答案时,T.C.的同等答案也更为简单。出现。我刚刚用循环实现了map::merge()