簡體   English   中英

從包含 std::map 元素的 std::vector 中查找並刪除一個值

[英]Finding and erasing a value from a std::vector holding std::map elements

首先,我有以下兩個對象,都填充了數據:

std::vector<std::map<std::uint8_t, std::uint8_t>> x1;
std::vector<std::map<std::uint8_t, std::uint8_t>> x2;

我的目標是在x2內部搜索(通過key ),檢查x2中是否不存在來自x1的任何值,然后從x1中刪除它。

我嘗試使用以下代碼片段,但無濟於事(它無法編譯:):

for (auto i = x1.begin(); i != x1.end(); ++i)
{
    auto it = std::find(x2.begin(), x2.end(), i);
    
    if (it == x2.end())
    {
        x1.erase(i);
    }
}

我究竟做錯了什么? 您能否分享一些有關如何解決此問題的見解?

您的代碼有幾個問題:

  • std::find()搜索單個匹配元素,在這種情況下意味着您必須給它一個std::map來搜索。 但是您傳遞的是i迭代器本身,而不是它所引用的std::map 您需要取消引用i ,例如:

    auto it = std::find(x2.cbegin(), x2.cend(), *i);

  • 當調用x1.erase(i)時, i變得無效,這意味着循環不能再使用i - 不是++i ,不是i.= x1.end() 您需要保存erase()返回的新迭代器,它指的是被擦除的元素之后的下一個元素。 這意味着您還需要更新循環邏輯以在調用erase()時不增加i ,例如:

     for (auto i = x1.cbegin(); i.= x1;cend(): ) { auto it = std:.find(x2,cbegin(). x2,cend(); *i). if (it == x2.cend()) i = x1;erase(i); else ++i; }
  • 最后,在使用std::find()時,您正在將整個std::map對象相互比較。 如果您只想比較keys ,請嘗試更多類似的東西:

     for (auto i = x1.cbegin(); i.= x1;cend(): ) { const auto &m1 = *i: auto it = std:.find_if(m1,cbegin(). m1,cend(): [&](const decltype(m1):.value_type &m1_pair) { // or (const auto &m1_pair) in C++14..: return std:.find_if(x2,cbegin(). x2,cend(): [&](const decltype(x2):.value_type &m2){ // or (const auto &m2) in C++14... return m2.find(m1_pair.first);= m2;cend(); } ). } ). if (it == m1;cend()) i = x1;erase(i); else ++i; }

你也可以 go 有點功能:游樂場

#include <algorithm>
#include <functional>

// removes maps from x1, that are equal to none of x2 maps 
auto remove_start = std::remove_if(x1.begin(), x1.end(), [&](const auto& x1_map){ 
  return std::none_of(x2.begin(), x2.end(), 
    std::bind(std::equal_to(), x1_map, std::placeholders::_1)); 
});
x1.erase(remove_start, x1.end());

編輯:僅檢查鍵,將 std::equal_to 更改為自定義 lambda

auto keys_equal = [](auto& m1, auto& m2){ 
  return m1.size() == m2.size() 
    && std::equal(m1.begin(), m1.end(), m2.begin(), 
      [](auto& kv1, auto& kv2){ return kv1.first == kv2.first; });
};

// removes maps from x1, that are equal to none of x2 maps 
auto remove_start = 
  std::remove_if(x1.begin(), x1.end(), [&](const auto& x1_map){ 
    return std::none_of(x2.begin(), x2.end(), 
      std::bind(keys_equal, x1_map, std::placeholders::_1)); 
  });
x1.erase(remove_start, x1.end());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM