¿Cuál es la mejor manera de determinar si un mapa STL contiene un valor para una clave determinada?
#include <map>
using namespace std;
struct Bar
{
int i;
};
int main()
{
map<int, Bar> m;
Bar b = {0};
Bar b1 = {1};
m[0] = b;
m[1] = b1;
//Bar b2 = m[2];
map<int, Bar>::iterator iter = m.find(2);
Bar b3 = iter->second;
}
Al examinar esto en un depurador, parece que iter
solo se trata de datos basura.
Si descomento esta línea:
Bar b2 = m[2]
Los espectáculos depurador que b2
es {i = 0}
. (Supongo que significa que usar un índice indefinido devolverá una estructura con todos los valores vacíos / sin inicializar).
Ninguno de estos métodos es tan bueno. Lo que realmente me gustaría es una interfaz como esta:
bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true;
}
return false;
}
¿Existe algo en este sentido?
Respuestas:
No. Con la clase de mapa stl, se usa
::find()
para buscar en el mapa y comparar el iterador devuelto constd::map::end()
entonces
Obviamente, puede escribir su propia
getValue()
rutina si lo desea (también en C ++, no hay razón para usarout
), pero sospecho que una vez que aprenda a usarlostd::map::find()
, no querrá perder su tiempo.Además, su código es ligeramente incorrecto:
m.find('2');
buscará en el mapa un valor clave que sea'2'
. IIRC, el compilador de C ++ convertirá implícitamente '2' en un int, lo que da como resultado el valor numérico para el código ASCII para '2' que no es lo que desea.Dado que su tipo de clave en este ejemplo es
int
que desea buscar así:m.find(2);
fuente
find
indica intención mucho mejor que locount
hace. Más,count
no devuelve el artículo. Si lees la pregunta del OP, él quiere verificar la existencia y devolver el elemento.find
hace eso.count
no.Mientras el mapa no sea un mapa múltiple, una de las formas más elegantes sería usar el método de conteo
El recuento sería 1 si el elemento está realmente presente en el mapa.
fuente
operator[]
).find
le ofrece laTryGetValue
semántica de .NET , que casi siempre es lo que usted (y específicamente el OP) desea.Ya existe con find pero no en esa sintaxis exacta.
Si desea acceder al valor si existe, puede hacer:
Con C ++ 0x y auto, la sintaxis es más simple:
Te recomiendo que te acostumbres a él en lugar de intentar crear un nuevo mecanismo para simplificarlo. Es posible que pueda reducir un poco de código, pero considere el costo de hacerlo. Ahora ha introducido una nueva función que las personas familiarizadas con C ++ no podrán reconocer.
Si desea implementar esto de todos modos a pesar de estas advertencias, entonces:
fuente
Acabo de notar que con C ++ 20 , tendremos
Eso devolverá verdadero si el mapa contiene un elemento con clave
key
.fuente
amap.find
regresaamap::end
cuando no encuentra lo que está buscando, se supone que debe verificarlo.fuente
Verifique el valor de retorno de
find
contraend
.fuente
Puede crear su función getValue con el siguiente código:
fuente
out = foundIter->second
out = foundIter->second
en lugar deout = *foundIter
Para resumir sucintamente algunas de las otras respuestas:
Si aún no está utilizando C ++ 20, puede escribir su propia
mapContainsKey
función:Si desea evitar muchas sobrecargas para
map
vsunordered_map
y diferentes tipos de clave y valor, puede hacer que esto sea unatemplate
función.Si está utilizando
C++ 20
o posterior, habrá unacontains
función incorporada:fuente
Si desea determinar si hay una clave en el mapa o no, puede usar la función miembro find () o count () del mapa. La función de búsqueda que se utiliza aquí, por ejemplo, devuelve el iterador a element o map :: end de lo contrario. En caso de conteo, el conteo devuelve 1 si se encuentra, de lo contrario, devuelve cero (o de lo contrario).
fuente
Boost multindex se puede utilizar para una solución adecuada. La siguiente solución no es la mejor opción, pero podría ser útil en algunos casos en los que el usuario asigna un valor predeterminado como 0 o NULL en la inicialización y desea verificar si el valor se ha modificado.
fuente