2017-09-15 78 views
0

我想删除一些满足条件的地图元素。我确实找到了解决方案,但我不知道如何使用它。如何从地图中删除元素

我:

std::map<char,int> first; 
first['a']=10; 
first['b']=60; 
first['c']=50; 
first['d']=70; 

给出的解决方案是:

namespace stuff { 
    template< typename ContainerT, typename PredicateT > 
    void erase_if(ContainerT& items, const PredicateT& predicate) { 
     for(auto it = items.begin(); it != items.end();) { 
      if(predicate(*it)) it = items.erase(it); 
      else ++it; 
     } 
    }; 
} 

我需要的是如何采用此功能删除其数量< = 50个元素:

using stuff::erase_if; 
int test_value = 50; // or use whatever appropriate type and value 
erase_if(container, [&test_value](item_type& item) { 
    return item.property <= test_value; // or whatever appropriate test 
}); 
+0

为什么你的拉姆达使用'ITEM_TYPE&当你的地图拥有item'了'char'? – NathanOliver

+0

为什么没有尝试使用[map :: erase](http://www.cplusplus.com/reference/map/map/erase/) –

+0

如果你只是想删除前两个元素,那么为什么你甚至需要那个功能?调用'erase'两次有什么问题? –

回答

1

你这里的问题是你的拉姆达在

erase_if(container, [&test_value](item_type& item) { 
    return item.property <= test_value; // or whatever appropriate test 
}); 

你有item_type& itemitem.property这不是什么你要。当你取消引用地图迭代器时,你会得到一个std::pair<const key_type, T>,这就是lambda需要采取的操作。我们可以使用

erase_if(container, [&test_value](const std::map<char,int>::value_type& item) { 
    return item.second <= test_value; 
}); 

但是,这意味着,如果我们改变地图使用,我们需要改变的item类型的其他一些重要的。为了避免这种情况,我们可以使用使用auto通用拉姆达像

erase_if(container, [&test_value](const auto& item) { 
    return item.second <= test_value; 
}); 
+0

是我所需要的,但我认为我需要修改函数erase_if的参数定义,因为它使用std :: pair –

+0

@ Blood-HaZaRd Oops。忘了迭代器返回一个值密钥对。让我解决这个问题。 – NathanOliver

+0

谢谢。有用。 –

4

为什么不使用std::map::erase?如在

first.erase(first.begin()); 

这将从地图中删除“第一个”项目。

如果你想删除某个特定的键,那么它只是相同的:

first.erase('a'); 
+0

对不起,我修改了这个问题,所以我想删除第一个和第三个 –

+0

@ Blood-HaZaRd和“第三”是否指特定的键(如''c'')?或者来自'begin()'的第三个? –

+2

@BorislavKostov不幸的是,map迭代器不是随机访问迭代器,所以你不能使用二进制'+'。 –