2012-06-20 16 views
11

私はキーとしてキーを区別しない文字列を持っています。 言語でサポートされているのですか、それとも自分で作成する必要がありますか? ありがとうGoで大文字と小文字を区別しないマップを作成するには?

編集:私は何を探していますが代わりにキー、私はマップを使用するたびに変換することを忘れないように有していると、デフォルトでそれを作るための方法がある

+1

手動で毎回Unicode折りたたみケースにマップします。 – tchrist

+0

SCL、この場合、Unicodeに関心がありますか?つまり、予期しないUnicodeコードポイントの拒否、または予想されるUnicodeコードポイントの処理に対する注意深い注意が必要ですか? – Sonia

+0

@sonia、こんにちは、私はASCIIだけを考えていました。しかし、あなたが尋ねているので、私はどのようにUnicodeを扱うでしょうか? –

答えて

10

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

タイプを「派生」することができます。 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) 
} 
+7

Unicodeデータでは小文字へのマッピングは機能せず、ASCIIの場合にのみ機能します。ここでは、小文字ではなく、Unicodeの折り畳み場にマッピングする必要があります。さもなければ、 'Σίσυφος'の小文字は'σίσυφος'であるため、大文字の小文字 'ΣΊΣΥΦΟΣ'は正しい'σίσυφοσ'です。これは実際にはすべてのものの折り畳みケースです。なぜUnicodeに別のマップがあるのか​​理解していますか?このような明示的な目的のために設計されていないものへの盲目的なマッピングのためには、あまりにも複雑なので、大文字、小文字、小文字、foldcaseというUnicodeのケーシングテーブルに4番目のカセットマップが存在します。 – tchrist

+0

それはFUDではない、@ソニア、それは事実だ。 Unicodeでは、すべて小文字または大文字を使用して大文字小文字を区別してテストすることはできません。 Unicodeのケーシングは複雑すぎるため、正規化とは何の関係もありません。フル・カセット・マップではなく、単純なものではありません。「toLower(ΣΊΣΥΦΟΣ)」と「toLower(Σίσυφος)」は、オリジナルが互いに大文字小文字を区別しないにもかかわらず、等しくありません。ユニコードでは、折り畳み箱を使用する必要があります。したがって、コードはバグであり、記載された要件を満たしていません。 – tchrist

+3

要件は文字列でした。 Goは、ASCIIではなく文字列にUnicodeを使用します。彼らは大文字と小文字を区別しない地図を要求した。これについて言及するのに夕方を気にせずに、ASCIIのみのソリューションを提供しました。私のコメントは、あなたがASCIIのみの制限がない、尋ねられた、言葉遣いのような質問に答えなかったので、トピックに関して完全にです。さて、この人は実際にはASCII以外のものしか持っていなかったので、一般的なケースでは間違っていても、あなたの解決策はひっくり返ってしまいました。 Unicodeで動作するソリューションを書くと、ASCIIでも動作しますが、その逆は成り立たないため、コードがバグです。 – tchrist

3

二possiblities:あなたが入力セットが大文字/小文字への変換は、正しい結果が得られますれる文字だけに制限されることが保証されている場合

  1. 変換は、/小文字を大文字に(真ではないかもしれません一部のUnicode文字用)

  2. それ以外のUnicode倍のケースに変換します

使用unicode.SimpleFold(rune) Cにユニコードルーンを反転させてフォールドケースにする。明らかに、これは単純なASCIIスタイルの事例マッピングよりも操作が劇的に高価ですが、他の言語にも移植性があります。ソース文字列からUnicodeルーンを抽出する方法を含め、これがどのように使われているかは、the source code for EqualsFoldを参照してください。

明らかに、この機能を別のパッケージに抽象化して、マップを使用する場所のどこにでも再実装するのは当然です。これは言うまでもないが、あなたは決して知らない。

+0

しかし、それはおそらくライブラリとして公開されているか、それを忘れる可能性があるので、エラーが発生しやすくなります。それを自動的に行うことができる派生型を作成する方法はありますか? –

+5

これは完全に間違っています。 ** 'S'、' s'、 's'は大文字と小文字が区別されず、'Σ'、 '''、' ' σ 'である。さらに、 'TSCHÜSS'、 '' TSCH ''、 '' '' '' '' '' '' '' '' '' '' '' 'tschüss''も大文字と小文字を区別しません。あなたはあなたがふりをすることはできません - すべてを大文字または小文字にマッピングしてください。それは単に機能しません。 – tchrist

+2

ASCIIを扱うことだけが分かっていることが分かっていればうまく動作します。これは彼のユースケースかもしれません。 –

関連する問題