2012-02-27 86 views
10

我正在跟蹤控制檯中的值。兩個人「對決」,我正在用字典來保存記錄的名字以及損害。帶兩個鍵的詞典?

var duels = new Dictionary<string, string>(); 
duels.Add("User1", "50"); 
duels.Add("User2","34"); 

我想這兩個用戶存儲相同的字典行中,因此它可以爲用戶1決鬥反對User2進行驗證。這樣,如果另一場決鬥開始,它不會干擾User1User2

duels.Add("KeyUser1","KeyUser2","50","34",.../*Other attributes of the duel*/); 

我需要兩把鑰匙,這樣我才能檢查用戶的傷害會發生在哪裏。傷害總是會轉移到另一個鍵 - 反之亦然。 我能做些什麼來完成這項工作?

謝謝。

+7

我會推薦使用這個元組。這裏有一篇相關的文章可能會引導你朝着正確的方向發展:http://stackoverflow.com/questions/1171812/multi-key-dictionary-in-c。祝你好運! – SMT 2012-02-27 03:52:54

+0

單個用戶可以一次參與多個決鬥嗎? – 2012-02-27 04:55:27

+0

涉及「User1」和「User2」的決鬥不同於涉及「User2」和「User1」的決鬥嗎? – 2012-02-27 05:08:13

回答

4
public class Duel 
{ 
    public string User1 {get; protected set;} 
    public string User2 {get; protected set;} 
    public Duel(string user1, string user2) 
    { 
    User1 = user1; 
    User2 = user2; 
    } 

    public HashSet<string> GetUserSet() 
    { 
    HashSet<string> result = new HashSet<string>(); 
    result.Add(this.User1); 
    result.Add(this.User2); 
    return result; 
    } 

    //TODO ... more impl 
} 

讓我們來進行一些決鬥吧。 CreateSetComparer允許字典使用集合的值進行平等測試。

List<Duel> duelSource = GetDuels(); 
Dictionary<HashSet<string>, Duel> duels = 
    new Dictionary<HashSet<string>, Duel>(HashSet<string>.CreateSetComparer()); 

foreach(Duel d in duelSource) 
{ 
    duels.Add(d.GetUserSet(), d); 
} 

,並找到一個決鬥:

HashSet<string> key = new HashSet<string>(); 
key.Add("User1"); 
key.Add("User2"); 
Duel myDuel = duels[key]; 
3

你可以嘗試做一個自定義數據類型的關鍵:

class DualKey<T> : IEquatable<DualKey<T>> where T : IEquatable<T> 
{ 
    public T Key0 { get; set; } 
    public T Key1 { get; set; } 

    public DualKey(T key0, T key1) 
    { 
     Key0 = key0; 
     Key1 = key1; 
    } 

    public override int GetHashCode() 
    { 
     return Key0.GetHashCode()^Key1.GetHashCode(); 
    } 

    public bool Equals(DualKey<T> obj) 
    { 
     return (this.Key0.Equals(obj.Key0) && this.Key1.Equals(obj.Key1)) 
      || (this.Key0.Equals(obj.Key1) && this.Key0.Equals(obj.Key0)); 
    } 
} 

然後用Dictionary<DualKey<string>, string>;

+1

我不想聽起來粗魯,但根據堆棧溢出規範,這應該是對原始問題的評論,而不是作爲答案提交。不希望你下臺投票:) – SMT 2012-02-27 03:54:03

+1

我還沒有試過嵌入式字典。那不是說有不同的關鍵字典嗎? – Kyle 2012-02-27 03:56:38

+1

@Tetreault啊,你是對的:(我的錯誤.. – Daryl 2012-02-27 03:57:59

4

快速。

class UserScores { 

    public string Key { get; set; } 

    public int User1Score { get; set; } 
    public int User2Score { get; set; } 

    public UserScores(string username1, string username2) 
    { 
      Key = username1 + ":" + username2; 
    } 
} 

void Main() 
{ 
    var userScore = new UserScores("fooUser", "barUser"); 

    var scores = new Dictionary<string, UserScores>(); 

    scores.Add(userScore.Key, userScore); 

    // Or use a list 

    var list = new List<UserScores>(); 

    list.Add(userScore); 

    list.Single (l => l.Key == userScore.Key); 
} 

雖然我認爲適當的解決方案會使用一個更好的思路UserScores對象來跟蹤特定的「決鬥」會議。

+1

如果'vin'和'yetish'在'viny'和'etish'戰鬥時會發生什麼?:) – 2012-02-27 03:59:57

+0

我喜歡將它們結合在一起的想法。我想我可以添加像'username1 +':「+ username2'和拆分':'來獲得'user [0]'和'user [1]'。 – Kyle 2012-02-27 04:00:34

+0

謝謝@PaulBellora,答案更新。 – 2012-02-27 04:20:26

2

由於一個人可以在最多一個決鬥在同一時間參與,你可以使用一個字典,直接「指數」 兩個端點在所有的決鬥,這樣的事情:

class Duel { 

    public Duel(string user1, string user2) { 
     Debug.Assert(user1 != user2); 
     User1 = user1; 
     User2 = user2; 
    } 

    public readonly string User1; 
    public readonly string User2; 
    public int User1Score; 
    public int User2Score; 

} 

class Program { 

    static void Main(string[] args) { 

     var dict = new Dictionary<string, Duel>(); 

     // Add a new duel. A single duel has two keys in the dictionary, one for each "endpoint". 
     var duel = new Duel("Jon", "Rob"); 
     dict.Add(duel.User1, duel); 
     dict.Add(duel.User2, duel); 

     // Find Jon's score, without knowing in advance whether Jon is User1 or User2: 
     var jons_duel = dict["Jon"]; 
     if (jons_duel.User1 == "Jon") { 
      // Use jons_duel.User1Score. 
     } 
     else { 
      // Use jons_duel.User2Score. 
     } 

     // You can just as easily find Rob's score: 
     var robs_duel = dict["Rob"]; 
     if (robs_duel.User1 == "Rob") { 
      // Use robs_duel.User1Score. 
     } 
     else { 
      // Use robs_duel.User2Score. 
     } 

     // You are unsure whether Nick is currently duelling: 
     if (dict.ContainsKey("Nick")) { 
      // Yup! 
     } 
     else { 
      // Nope. 
     } 

     // If Jon tries to engage in another duel while still duelling Rob: 
     var duel2 = new Duel("Jon", "Nick"); 
     dict.Add(duel2.User1, duel); // Exception! Jon cannot be engaged in more than 1 duel at a time. 
     dict.Add(duel2.User2, duel); // NOTE: If exception happens here instead of above, don't forget remove User1 from the dictionary. 

     // Removing the duel requires removing both endpoints from the dictionary: 
     dict.Remove(jons_duel.User1); 
     dict.Remove(jons_duel.User2); 

     // Etc... 

    } 

} 

這僅僅是一個基本的想法,你可能會考慮在自己的類包裝此功能...