[英]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.