1

私が以下に持っているものよりも悪くないパフォーマンスをするこれに良い代替案があるかどうか疑問に思いますか?実際のswitchステートメントには、他の英語以外の文字用の追加セクションがあります。

1行に複数のcaseステートメントを配置したいのですが、StyleCopはそれを嫌い、結果としてリリースビルドに失敗することに注意してください。

        var retVal = String.Empty;
        switch(valToCheck)
        {
            case "é": 
            case "ê": 
            case "è": 
            case "ë":
                retVal = "e";
                break;
            case "à": 
            case "â": 
            case "ä": 
            case "å":
                retVal = "a";
                break;

            default:
                retVal = "-";
                break;
        }
4

6 に答える 6

4

最初に頭に浮かぶのはDictionary<char,char>()
(文字を扱っているので文字列ではなく文字を好む)です

Dictionary<char,char> dict = new Dictionary<char,char>();
dict.Add('å', 'a');
......

次に、スイッチ全体を削除できます

char retValue;
char testValue = 'å';
if(dict.TryGetValue(testValue, out retValue) == false)
   retVal = '-';
于 2012-07-25T20:23:42.593 に答える
1

さて、この変換を行うことから始めます。

public class CharacterSanitizer
{
    private static Dictionary<string, string> characterMappings = new Dictionary<string, string>();
    static CharacterSanitizer()
    {
        characterMappings.Add("é", "e");
        characterMappings.Add("ê", "e");
        //...
    }

    public static string mapCharacter(string input)
    {
        string output;
        if (characterMappings.TryGetValue(input, out output))
        {
            return output;
        }
        else
        {
            return input;
        }
    }
}

これで、文字マッピングがコードではなくデータの一部になる位置にいます。ここで値をハードコーディングしましたが、この時点では、マッピングをファイルに保存し、ファイルを読み込んで、それに応じて辞書にデータを入力するだけです。このようにして、caseステートメントを1ビットのテキストファイル(コード外)に減らすことでコードを大幅にクリーンアップできるだけでなく、再コンパイルせずにコードを変更できます。

于 2012-07-25T20:24:03.590 に答える
1

小さな範囲のチェックを行い、ASCIIを確認できます。

InRange(val, min, max)数が範囲内にあるかどうかをチェックすると仮定します。

if(InRange(System.Convert.ToInt32(valToCheck),232,235))
  return 'e';
else if(InRange(System.Convert.ToInt32(valToCheck),224,229))
  return 'a';

これはコードを少し混乱させ、使用される標準に依存しますが、おそらく考慮すべきことがあります。

于 2012-07-25T20:25:10.117 に答える
1

この回答は、そのswitchステートメントを単一の文字だけでなく文字列に適用することを前提としています(ただし、それでも機能します)。

最善のアプローチは、このStackOverflowの回答で概説されているもののようです。

LINQを使用するように調整しました。

var chars = from character in valToCheck.Normalize(NormalizationForm.FormD)
            where CharUnicodeInfo.GetUnicodeCategory(character)
                    != UnicodeCategory.NonSpacingMark
            select character;
return string.Join("", chars).Normalize(NormalizationForm.FormC);

のusingディレクティブが必要になりますSystem.Globalization;

サンプル入力:

string valToCheck = "êéÈöü";

サンプル出力:

eeEou
于 2012-07-25T20:35:24.413 に答える
1

Michael KaplanのRemoveDiacritics()に基づいて、次のようなことができます。

static char RemoveDiacritics(char c)
{
    string stFormD = c.ToString().Normalize(NormalizationForm.FormD);
    StringBuilder sb = new StringBuilder();

    for (int ich = 0; ich < stFormD.Length; ich++)
    {
        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
        if (uc != UnicodeCategory.NonSpacingMark)
        {
            sb.Append(stFormD[ich]);
        }
    }

    return (sb.ToString()[0]);
}

switch(RemoveDiacritics(valToCheck))
{
    case 'e':
        //...
        break;
    case 'a':
        //...
        break;
        //...
}

または、場合によっては:

retval = RemoveDiacritics(valToCheck);
于 2012-07-25T20:35:59.320 に答える
0

Containsの代わりに使用してくださいswitch

var retVal = String.Empty;

string es = "éêèë";
if (es.Contains(valToCheck)) retVal  = "e";
//etc.
于 2012-07-25T20:26:03.687 に答える