2010-05-06 1030 views
43

我的使用情况:如何查找std :: map中是否存在元素?

map<string, Car> cars; 
bool exists(const string& name) { 
    // somehow I should find whether my MAP has a car 
    // with the name provided 
    return false; 
} 

能否请您建议最好的和最优雅的方式做到这一点在C++?谢谢。

回答

42

当然,使用迭代器

map<string,Car>::const_iterator it = cars.find(name); 
return it!=cars.end(); 
+5

既然你不会改变'cars',最好是得到'const_iterator'。 – kennytm 2010-05-06 14:42:23

+0

好点。编辑... – Tom 2010-05-06 14:43:02

+0

但是,如果'cars'不是const,'cars.find(name)'将返回一个'iterator',它必须转换为'const_iterator','cars.end()'将返回一个'iterator',然后将其与'it'进行比较时转换为'const_iterator'。为什么要对抗它;为什么不使用'iterator'? – 2010-05-06 17:24:00

5
bool exists(const string& name) 
{ 
    return cars.find(name) != cars.end(); 
} 
+0

如果它是一个成员,使函数'const'? – 2010-05-06 14:41:11

+1

如果是会员,那么是的。 – 2010-05-06 14:42:47

70
return cars.find(name) != cars.end(); 
+0

这是我会用的答案! – 2015-03-19 14:21:18

1
bool exists(const std::map<std::string, Car>& cars, const std::string& name) { 
    return cars.end() != cars.find(name); 
} 
+0

为什么不通过使它成为模板函数来使它更通用?但它可能不会满足优雅的要求更好.. – foraidt 2010-05-06 15:01:17

+0

@mxp,请参阅我的解决方案(http://stackoverflow.com/questions/2781899/how-to-find-whether-an-element-exists -in-stdmap/2782084#2782084)。 – 2010-05-06 15:04:31

2

std::map::find(const key_type& x);

如果该项目不存在,它返回map::end

21

你也可以使用

bool exists(const string& name) { 
    return cars.count(name) != 0; 
} 
+0

'!= 0'可选。 – Potatoswatter 2010-05-06 15:31:39

+12

@Patatoswatter但是清楚地说明了正在测试的内容。它纯粹是一个风格问题,但我倾向于不依赖隐式int来布尔转换。 – KeithB 2010-05-06 15:51:05

+4

@Potatoswatter:明确的比较将抑制VC++警告(“性能警告:强制整数为bool”);) – UncleBens 2010-05-06 16:05:42

7

什么:

template <typename KeyType, typename Collection> 
bool exists_in(Collection const& haystack, KeyType const& needle) { 
    return std::find(haystack.begin(), haystack.end(), needle) != haystack.end(); 
} 

template <typename K, typename V> 
bool exists_in(std::map<K,V> const& haystack, K const& needle) { 
    return haystack.find(needle) != haystack.end(); 
} 

这使得与任何标准集装箱exists_in工作通过std::find,并使用一个特殊的版本std::map,因为它提供了一个更有效的搜索替代。您可以根据需要添加其他专业化(例如,std::set等)。

+4

通过const引用传递所有内容。 – UncleBens 2010-05-06 16:07:18

15

除了find()中的iterator-Value和与.end()的比较,还有另一种方法:map :: count。

你可以用特定的键调用map :: count(key)它会返回给定密钥的条目数量。对于具有唯一键的映射,结果将为0或1.由于multimap也存在以及相同的界面,因此存在的安全方面更好地与!= 0进行比较。

为你的榜样,这是

return (cars.count(name)>0); 

我看到的好处是 1.短代码, 2.无论从任何的优化库可以在内部应用,使用其代表性的细节好处。

0
#define itertype(v) typeof((v).begin()) 
itertype(cars) it = cars.find(name); 
return it != cars.end(); 
+0

为什么不使用'auto'而不是这个宏呢? 'auto it = cars.find(name);' – 2017-06-04 18:15:55

+0

欢迎来到SO。这个答案实际上并没有添加任何新的东西,这些东西在(现在很多的)现有答案中都没有涉及。考虑删除你的答案,也许看起来反应回答尚未接受答案的问题。 – 2017-06-04 21:46:57