2012-02-27 95 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... 

    } 

} 

这仅仅是一个基本的想法,你可能会考虑在自己的类包装此功能...