Sé que puedo iterar sobre un mapa m
,
for k, v := range m { ... }
y busque una clave, pero ¿hay una manera más eficiente de probar la existencia de una clave en un mapa?
No pude encontrar la respuesta en las especificaciones del idioma .
dictionary
go
go-map
grokus
fuente
fuente
Respuestas:
Respuesta de una línea:
Explicación:
if
Las declaraciones en Go pueden incluir tanto una condición como una declaración de inicialización. El ejemplo anterior usa ambos:inicializa dos variables:
val
recibirá el valor de "foo" del mapa o un "valor cero" (en este caso, la cadena vacía) yok
recibirá un bool que se establecerátrue
si "foo" estaba realmente presente en el mapaevalúa
ok
, que serátrue
si "foo" estaba en el mapaSi "foo" está realmente presente en el mapa, el cuerpo de la
if
declaración se ejecutará yval
será local en ese ámbito.fuente
var val string = ""
seguirá siendo el mismo,val, ok :=
crea una nueva variable local con el mismo nombre que solo es visible en ese bloque.if key in dict
.Además de la especificación del lenguaje de programación The Go , debe leer Effective Go . En la sección de mapas , dicen, entre otras cosas:
fuente
Busqué en la lista de correos electrónicos y encontré una solución publicada por Peter Froehlich el 15/11/2009.
O, más compactamente,
Tenga en cuenta que, utilizando esta forma de la
if
declaración, las variablesvalue
yok
solo son visibles dentro de lasif
condiciones.fuente
_, ok := dict["baz"]; ok
. La_
parte arroja el valor en lugar de crear una variable temporal.Respuesta corta
Ejemplo
Aquí hay un ejemplo en Go Playground .
Respuesta larga
Según la sección de Mapas de Effective Go :
fuente
Como se señaló en otras respuestas, la solución general es usar una expresión de índice en una asignación de la forma especial:
Esto es lindo y limpio. Sin embargo, tiene algunas restricciones: debe ser una asignación de forma especial. La expresión del lado derecho debe ser solo la expresión del índice del mapa, y la lista de expresiones del lado izquierdo debe contener exactamente 2 operandos, el primero al que se puede asignar el tipo de valor y el segundo al que
bool
se puede asignar un valor. El primer valor del resultado de esta forma especial será el valor asociado con la clave, y el segundo valor indicará si realmente hay una entrada en el mapa con la clave dada (si la clave existe en el mapa). La lista de expresiones del lado izquierdo también puede contener el identificador en blanco si uno de los resultados no es necesario.Es importante saber que si el valor del mapa indexado es
nil
o no contiene la clave, la expresión del índice se evalúa como el valor cero del tipo de valor del mapa. Así por ejemplo:Pruébalo en Go Playground .
Entonces, si sabemos que no usamos el valor cero en nuestro mapa, podemos aprovechar esto.
Por ejemplo, si el tipo de valor es
string
, y sabemos que nunca almacenamos entradas en el mapa donde el valor es la cadena vacía (valor cero para elstring
tipo), también podemos probar si la clave está en el mapa comparando los valores no especiales forma de (resultado de) la expresión de índice al valor cero:Salida (pruébalo en Go Playground ):
En la práctica, hay muchos casos en los que no almacenamos el valor de valor cero en el mapa, por lo que puede usarse con bastante frecuencia. Por ejemplo, las interfaces y los tipos de función tienen un valor cero
nil
, que a menudo no almacenamos en los mapas. Por lo tanto, se puede probar si una clave está en el mapa comparándola connil
.El uso de esta "técnica" también tiene otra ventaja: puede verificar la existencia de varias claves de manera compacta (no puede hacerlo con el formulario especial "coma ok"). Más sobre esto: compruebe si la clave existe en varios mapas en una condición
Obtener el valor cero del tipo de valor cuando se indexa con una clave no existente también nos permite usar mapas con
bool
valores convenientemente como conjuntos . Por ejemplo:Sale (pruébalo en Go Playground ):
Ver relacionado: ¿Cómo puedo crear una matriz que contenga cadenas únicas?
fuente
T
envar v, ok T = a[x]
? nook
debe ser bool?map[bool]bool
yT
esbool
, pero también funciona si el mapa es de tipomap[interface{}]bool
yT
esinterface{}
; Además, también funciona con tipos personalizados que tienenbool
como tipo subyacente, ver todo en Go Playground . Entonces, dado que esa forma es válida con múltiples tipos sustituidosT
, es por eso queT
se usa el general . Tipo deok
puede ser cualquier cosa a la que se le pueda asignar un sin tipobool
.mejor manera aquí
fuente
fuente
Luego, ve a ejecutar maps.go somestring existe? verdad no existe? falso
fuente
_, ok = m["somestring"]
debería ser=_, ok := m["somestring"]
Se menciona en "Expresiones de índice" .
fuente
Se puede usar una asignación de dos valores para este propósito. Por favor revise mi programa de muestra a continuación
fuente