2012-10-29 39 views
2

我有一本字典:C#字典地圖

Dictionary<ICD_Map2, string> maps = new Dictionary<ICD_Map2, string>(); 

    public class ICD_Map2 
    { 
     public string call_type {get; set; } 
     public string destination{get; set;} 

    } 

maps.Add(new ICD_Map2() {call_type = "Mobile SMS", destination = "Australia"},"Local Text"); 
maps.Add(new ICD_Map2() {call_type = "Mobile SMS", destination = "International"},"International Text"); 

所以,我要的是,當我通過兩個變量:

案例1個變量1 = 「手機短信」 & &變量2 =「澳大利亞「我想要一個函數返回」本地文本「

案例2」國際文本「取決於我的輸入變量匹配ICD_Map2定義」Mobile SMS「和」International「。」

如何構造此映射函數以從一組結果(如果有多個)返回集合的第一個?這是一個非常簡單的例子,我有超過100個映射。

+2

的字典,只要正確使用,不超過1分的結果 - 這是一個獨特的,關鍵值映射(該值不必是唯一的)。 –

回答

3

使用字典,關鍵需要支持同性運算。例如:

public class ICD_Map2 : IEquatable<ICD_Map2> 
{ 
    public ICD_Map2(string callType, string destination) { 
     CallType = callType; 
     Destination = destination; 
    } 
    public override int GetHashCode() { 
     int result = 17; 
     result = -13 * result + 
      (CallType == null ? 0 : CallType.GetHashCode()); 
     result = -13 * result + 
      (Destination == null ? 0 : Destination.GetHashCode()); 
     return result; 
    } 
    public override bool Equals(object other) { 
     return Equals(other as ICD_Map2); 
    } 
    public bool Equals(ICD_Map2 other) { 
     if(other == null) return false; 
     if(other == this) return true; 
     return CallType == other.CallType && Destination == other.Destination; 
    } 
    public string CallType {get; private set; } 
    public string Destination{get; private set;} 
} 

注意使其只讀是故意的:可變的鍵會造成巨大的問題 - 避免這種情況。除非你有第二個字典

var key = new ICD_Map2("Mobile SMS", "Australia"); 
string result; 
if(maps.TryGetValue(key, out result)) { 
    Console.WriteLine("found: " + result); 
} 

反向查找是有問題的,並且不能被優化:

現在你可以使用這個作爲重點,例如。通過簡單的操作(表現爲O(n))將是:

string result = "International Text"; 
var key = (from pair in maps 
      where pair.Value == result 
      select pair.Key).FirstOrDefault(); 
if(key != null) { 
    Console.WriteLine("found: " + key); 
} 

全部放在一起:

static void Main() 
{ 
    Dictionary<ICD_Map2, string> maps = new Dictionary<ICD_Map2, string> { 
     {new ICD_Map2 ("Mobile SMS", "Australia"),"Local Text"}, 
     {new ICD_Map2 ("Mobile SMS", "International"),"International Text"} 
    }; 

    // try forwards lookup 
    var key = new ICD_Map2("Mobile SMS", "Australia"); 
    string result; 
    if (maps.TryGetValue(key, out result)) 
    { 
     Console.WriteLine("found: " + result); 
    } 

    // try reverse lookup (less efficient) 
    result = "International Text"; 
    key = (from pair in maps 
       where pair.Value == result 
       select pair.Key).FirstOrDefault(); 
    if (key != null) 
    { 
     Console.WriteLine("found: " + key); 
    } 
} 
0

我認爲這應該工作,將仔細檢查以秒:

maps.Where(a => (String.IsNullOrEmpty(var1) || String.Compare(a.Key.call_type, var1) == 0) 
      && (String.IsNullOrEmpty(var2) || String.Compare(a.Key.destination, var2) == 0)) 
    .FirstOrDefault().Value` 
+0

它確實使使用無意義的字典,但...因爲這並不*字典代碼 –

+0

@MarcGravell出於好奇的任何*,還有什麼可他用類似於ICD_Map對象和字符串之間的映射受益? –

+0

@MohammadBanisaeid就可以把關鍵equatable,他可以使用自定義比較,他可以使用元組(其中有內置的equatable實現),他可以使用匿名類型等 –

0

你必須落實ICD_Map2 IEquitable接口和重寫GetHashCode功能(最好是重載Equals(對象),也儘管它不是必要的詞典使用通用IEquitable界面找到鑰匙)

3

雖然有相當多,你可以做到這一點的一些方法,我會presonally用最快,最簡單的是LINQ的FirstOrDefault這樣的:

string var1 = "Mobile SMS"; 
string var2 = "Australia"; 

var item = maps.FirstOrDefault(e => e.Key.call_type == var1 && e.Key.destination == var2); 
string result = (item == null) ? "No value" : item.Value; 

在這種情況下,如果沒有相應的匹配,你會最終result被空。

+0

此不作任何使用的事實,這是一本字典,雖然 –

+0

@MarcGravell我絕對同意,我只是回答問題的最基本的組成部分。 –

2

構建自定義比較:

public class CusComparer: IEqualityComparer<ICD_Map2> 
{ 
    public bool Equals(ICD_Map2 x, ICD_Map2 y) 
    { 
     return x.call_type.Equals(y.call_type) 
       && x.destination.Equals(y.destination); 
    } 

    public int GetHashCode(ICD_Map2 obj) 
    { 
     return obj.call_type.GetHashCode() 
       ^obj.destination.GetHashCode(); 
    } 
} 

記住Dictionary有另一個重載構造與接受IEqualityComparer

var maps = new Dictionary<ICD_Map2, string>(new CusComparer()); 

maps.Add(new ICD_Map2() { 
       call_type = "Mobile SMS", 
       destination = "Australia"}, 
     "Local Text"); 

maps.Add(new ICD_Map2() { 
      call_type = "Mobile SMS", 
      destination = "International"}, 
     "International Text"); 

所以,你可以得到:

var local = maps[new ICD_Map2() { 
        call_type = "Mobile SMS", 
        destination = "Australia"}];