16

我想要一个键不敏感的字符串作为键。它是由语言支持还是我必须自己创建?谢谢你

编辑:我正在寻找的是一种默认方式,而不是每次使用地图时都必须记住转换键。

4

3 回答 3

12

编辑:我的初始代码实际上仍然允许映射语法,因此允许绕过这些方法。这个版本更安全。

您可以“派生”一种类型。在 Go 中,我们只说声明。然后你在你的类型上定义方法。只需要一个非常薄的包装器就可以提供您想要的功能。但请注意,您必须使用普通的方法调用语法调用 get 和 set。没有办法保留内置地图的索引语法或可选的 ok 结果。

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)
}
于 2012-06-20T18:16:51.537 回答
3

两种可能:

  1. 如果您是输入集,则转换为大写/小写保证仅限于转换为大写/小写将产生正确结果的字符(对于某些 Unicode 字符可能不正确)

  2. 否则转换为 Unicode 折叠大小写:

用于unicode.SimpleFold(rune)将 unicode 符文转换为折叠大小写。显然,这比简单的 ASCII 风格的大小写映射要昂贵得多,但它也更易于移植到其他语言。请参阅EqualsFold 的源代码以了解它是如何使用的,包括如何从源字符串中提取 Unicode 符文。

显然,您会将这个功能抽象到一个单独的包中,而不是在使用地图的任何地方重新实现它。这应该不言而喻,但你永远不会知道。

于 2012-06-20T17:21:53.770 回答
0

这是比strings.ToLower更强大的东西,您可以使用golang.org/x/text/cases包。例子:

package main
import "golang.org/x/text/cases"

func main() {
   s := cases.Fold().String("March")
   println(s == "march")
}

如果你想使用标准库中的东西,我运行了这个测试:

package main

import (
   "strings"
   "unicode"
)

func main() {
   var (
      lower, upper int
      m = make(map[string]bool)
   )
   for n := '\u0080'; n <= '\u07FF'; n++ {
      q, r := n, n
      for {
         q = unicode.SimpleFold(q)
         if q == n { break }
         for {
            r = unicode.SimpleFold(r)
            if r == n { break }
            s, t := string(q), string(r)
            if m[t + s] { continue }
            if strings.ToLower(s) == strings.ToLower(t) { lower++ }
            if strings.ToUpper(s) == strings.ToUpper(t) { upper++ }
            m[s + t] = true
         }
      }
   }
   println(lower == 951, upper == 989)
}

所以可以看出,ToUpper是稍微好一点的选择。

于 2020-12-24T02:03:14.677 回答