今天要分享的笨問題是:

寫程式時偶爾會需要Key不分大小寫的Hashtable(Dictionary<string, string>),大家都是怎麼解決的呢? 我最近才頓悟...

using System;
using System.Collections.Generic;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //我以前都這麼處理不分大小寫的Hashtable
            Dictionary<string, int> sillyBoy = 
                new Dictionary<string, int>();
            //新增時將所有Key強迫轉小寫
            sillyBoy.Add("Darkthread".ToLower(), 9999);
            //比較時也強迫轉小寫就好了呀
            if (sillyBoy.ContainsKey("DARKTHREAD".ToLower()))
                Console.WriteLine("阿母啊! 哇行公啊~~");
            //當時覺得我好會想辦法解問題,沒想到自己根本是
            //笨小孩笨小孩笨小孩笨小孩笨小孩笨小孩笨小孩笨小孩
 
            //原來,Dictionary<T, T>的建構式可傳入Comparer當參數
            Dictionary<string, int> dict =
                new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
            dict.Add("Darkthread", 32767);
            Console.WriteLine(dict["DARKTHREAD"]);
            Console.WriteLine(dict["darkthread"]);
            //是的,醬子就可以搞定。我以後不會再阿呆了
            Console.Read();
        }
    }
}

Comments

# by Leo

我也是笨小孩笨小孩笨小孩笨小孩笨小孩笨小孩 >"<; 文章收下了,感恩~

# by laneser

嗯嗯, 還有 String.Compare ... 我常改的 code 是 if (str1.ToLower() == str2.ToLower()) 改為 if (string.Compare(str1,str2, true)) 不過, 原本的 code 也是以前的我 (笨小孩!!!) 寫的阿~

# by jain

原來我也笨很久了~~

# by Bibby

有笨過得是不是都要來簽到阿!!XD

# by aliku

"阿母啊! 哇行公啊~~" 後面這一句是什意思呢?? (笨小孩之一)

# by Samuel

如果考慮日後其他的工程師要接手維護的話...第一種是最容易懂的..不見的得不好.

# by respen optimal

其實我認為你原來的做法比較聰明. 因為你如果每次比較都要IgnoreCase,就等於每次都要化成小寫或大寫,才來比較.不如第一次就化成小寫,反而比較有效率.

# by

那請問繼承過後的dictionary該如何指定,不分大小寫呢? 例如 class a : dictionary<string,int>{ public int getint(string v) { return this[v]; } }

# by Jeffrey

to 谷,你要加入空白建構式以及接收比較函式的建構式,如下例: class a : Dictionary<string, int> { public a() { } public a(IEqualityComparer<string> comparer) : base(comparer) { } public int getint(string v) { return this[v]; } } class Program { static void Main(string[] args) { var test = new a(StringComparer.OrdinalIgnoreCase); } } 如果要寫死永遠不分大小寫,則可以改成這樣: public a() : base(StringComparer.OrdinalIgnoreCase) { }

# by 小福

可是如果已經有一個dictionary的話,可以將現有的改成不分大小寫嗎? 例一: dictionary<string,string> a; a = cache["a"] as dictionary<string,string>; 我不知道cache中的 dictionary是不是不分大小寫的。 例二: B <----已經是一個dictionary<string,string> 可以直接變更嗎? 目前我用的方式是: 解一: new 一個新的指定不分大小寫,然後把cache as給他 解二:用Todictionary去弄。但筆數大,效能就不好了

# by Jeffrey

to 小福,不允許事後直接變更大小寫識別規則有其考量,例如:原本區分大小寫,故出現Key "A"與Key "a"並存,要轉為不分大小寫就會出錯。不太懂解一的做法,as是轉型為另一型別,若原本沒有繼承或介面關係,轉型應會失敗吧?解二ToDictionary()產生新物件時應無法指定不區分大小寫。能給明確一點的範例嗎?

# by 小福

解一的部份是說,我有一個cache他是dictionary但我不知道是不是不分大小寫,但是我要使用他,所以,我用另一個dictionary去接他,但要變成不分大小寫。 解二是說:若我原有的dictonary,我要給另一個dictionary去用,但要變成不分大小寫時使用,todictionary是可以指定不分大小寫

# by Jeffrey

to 小福, 補充一下我的疑惑,解一的語法是 Cache["a"] as T,T是一個型別,而且是Dictionary<string, string>可以轉型過去的型別,我想不出方法在讓轉型對象的型別是不分大小寫的Dictionary<string, string>(); 解二可以寫成ToDictionary(o => o.Key.ToLower(), o => o.Value)轉型成Key一律小寫(或大寫)的Dictionary<string, string>,但它不像 new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)可以直接支援不分大小寫,而是在取值自行將Key轉小寫再比對。這是你預期的做法嗎?

# by 小福

謝謝你,我想重點應該就是,已經原有的dictionary,不可以讓他變成不分大小寫,因為就像您說的那樣,a A的問題。 謝謝

Post a comment