2012-06-20 6 views
11

Quiero tener una cadena insensible a las teclas como clave. ¿Es compatible con el idioma o tengo que crearlo yo mismo? graciasCómo crear un mapa insensible a mayúsculas y minúsculas en Go?

Editar: Lo que estoy buscando es una manera de hacer que por defecto en lugar de tener que recordar para convertir las llaves cada vez que utilizo el mapa.

+1

Mapa de la carpeta Unicode cada vez, manualmente. – tchrist

+0

SCL, ¿te preocupa Unicode en este caso? Es decir, ¿sus necesidades incluyen el rechazo de puntos de código Unicode inesperados o una atención cuidadosa al manejo de los puntos de código Unicode esperados? – Sonia

+0

@sonia, hola, estaba considerando solo ASCII. Pero ya que estás preguntando, ¿cómo manejaría Unicode? –

Respuesta

10

Editar: Mi código inicial aún permitía la sintaxis del mapa y permitía eludir los métodos. Esta versión es más segura.

Puede "derivar" un tipo. En Go solo decimos declarar. Luego defines los métodos en tu tipo. Solo se necesita una envoltura muy delgada para proporcionar la funcionalidad que desea. Sin embargo, tenga en cuenta que debe llamar a get y establecer con sintaxis de llamada de método ordinario. No hay forma de mantener la sintaxis de índice o el resultado de autorización opcional que tienen los mapas integrados.

package main 

import (
    "fmt" 
    "strings" 
) 

type ciMap struct { 
    m map[string]bool 
} 

func newCiMap() ciMap { 
    return ciMap{m: make(map[string]bool)} 
} 

func (m ciMap) set(s string, b bool) { 
    m.m[strings.ToLower(s)] = b 
} 

func (m ciMap) get(s string) (b, ok bool) { 
    b, ok = m.m[strings.ToLower(s)] 
    return 
} 

func main() { 
    m := newCiMap() 
    m.set("key1", true) 
    m.set("kEy1", false) 
    k := "keY1" 
    b, _ := m.get(k) 
    fmt.Println(k, "value is", b) 
} 
+7

La asignación a minúsculas no funciona para datos Unicode, solo para ASCII. Debería estar mapeando en el plegado de Unicode aquí, no en minúsculas. De lo contrario, la suya es una tarea de Sísifo, ya que la letra minúscula de 'Σίσυφος' es' σίσυφος', mientras que minúscula de su mayúscula, 'ΣΊΣΥΦΟΣ', es la correcta 'σίσυφοσ', que es de hecho el doblez de todos esos. ¿Ahora entiendes por qué Unicode tiene un mapa separado? Los mapas de caso son demasiado complejos para mapear ciegamente a cualquier cosa no diseñada para ese propósito explícito, y por lo tanto, la presencia de un 4 ° mapa de casos en las tablas de envoltura de Unicode: mayúscula, título, minúscula, doblez. – tchrist

+0

No es FUD, @Sonia, es un hecho. En Unicode no se puede usar mayúsculas o minúsculas para probar las mayúsculas y minúsculas de manera insensible. La carcasa Unicode es demasiado complicada para eso, y tampoco tiene nada que ver con la normalización. El mapeo simple simple no completo es suficiente para demostrar el defecto inherente: 'toLower (ΣΊΣΥΦΟΣ)' y 'toLower (Σίσυφος)' no son iguales a pesar de que sus originales son insensibles a las mayúsculas y minúsculas entre sí. Debe usar foldcase en Unicode. Por lo tanto, su código es defectuoso y no cumple con los requisitos establecidos. – tchrist

+3

El requisito era cadenas. Go usa Unicode para cadenas, no ASCII. Pidieron un mapa insensible a mayúsculas y minúsculas. Proporcionó una solución solo ASCII sin molestarse tarde en mencionar esto. Mis comentarios se centran perfectamente en el tema, porque no respondió la pregunta tal como se le preguntó y redactó, que no tenía restricciones de ASCII. Ahora bien, resulta que esta persona en realidad no tenía nada más que ASCII, por lo que su solución se coló aunque estaba mal en el caso general. Escriba soluciones que funcionen para Unicode, y también funcionarán para ASCII, pero lo contrario no es válido, razón por la cual su código tiene errores. – tchrist

3

dos posibilidades:

  1. Convertir a mayúsculas/minúsculas si estás conjunto de entrada se garantiza que se limita sólo a los personajes para los que una conversión a mayúsculas/minúsculas producirá resultados correctos (no puede ser verdad para algunos caracteres Unicode)

  2. Convertir a Unicode caso pliegue de otro modo:

uso unicode.SimpleFold(rune) ac onvertir una runa Unicode para doblar la caja. Obviamente, esta es una operación mucho más costosa que la simple asignación de casos al estilo ASCII, pero también es más portátil para otros idiomas. Consulte the source code for EqualsFold para ver cómo se usa esto, incluso cómo extraer las runas Unicode de su cadena de origen.

Obviamente, usted abstraería esta funcionalidad en un paquete separado en lugar de volver a implementarlo en cualquier lugar que utilice el mapa. Esto debería ser evidente, pero nunca se sabe.

+0

Pero eso sería propenso a errores ya que tal vez está expuesto como una biblioteca o puedo olvidar hacerlo. ¿Hay alguna manera de crear un tipo derivado que pueda hacerlo automáticamente? –

+5

Esto es completamente incorrecto. ** Debes * usar * las reglas de plegado de mayúsculas de Unicode. ** Considera que 'S',' s' y 's' son todas insensibles a mayúsculas/minúsculas, como también lo son' Σ', 'ς' y' σ'. Además, 'TSCHÜSS',' TSCHÜẞ', 'tschüß',' tschüss' también son insensibles a mayúsculas y minúsculas. No puede hacer lo que pretende: mapear todo en mayúsculas o minúsculas. Eso simplemente no funciona. – tchrist

+2

Funciona bien si sabes que solo tratarás con ASCII, que podría ser su caso de uso. –

Cuestiones relacionadas