16

キーとしてキーを区別しない文字列が必要です。言語でサポートされていますか、それとも自分で作成する必要がありますか? ありがとうございました

編集:私が探しているのは、マップを使用するたびにキーを変換することを覚えておく必要がなく、デフォルトで作成する方法です。

4

3 に答える 3

12

編集:私の最初のコードでは、実際にはまだマップ構文が許可されていたため、メソッドをバイパスできました。このバージョンはより安全です。

タイプを「派生」させることができます。Go では、declare と言うだけです。次に、型にメソッドを定義します。必要な機能を提供するには、非常に薄いラッパーが必要です。ただし、通常のメソッド呼び出し構文で 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

2 つの可能性:

  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 に答える