字典有两个键
本文关键字:两个 字典 | 更新日期: 2023-09-27 18:25:49
我正在跟踪控制台中的值。两个人互相"决斗",我用字典把名字和造成的伤害一起记录下来。
var duels = new Dictionary<string, string>();
duels.Add("User1", "50");
duels.Add("User2","34");
我试图将两个用户存储在同一个字典行中,这样就可以验证为User1正在与User2
决斗。这样,如果另一场决斗开始,它就不会干扰User1
或User2
。
duels.Add("KeyUser1","KeyUser2","50","34",.../*Other attributes of the duel*/);
我需要两把钥匙,这样我就可以检查用户的损坏情况。损坏总是发生在另一把钥匙上,反之亦然。我该怎么做才能让它发挥作用?
谢谢。
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];
您可以尝试为密钥创建一个自定义数据类型:
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>
;
一些快速的东西。
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对象来跟踪特定的"决斗"会话。
由于一个人一次最多只能参与一场决斗,因此您可以使用一个字典在所有决斗中直接"索引"两个端点,类似于以下内容:
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...
}
}
这只是一个基本想法,您可以考虑将此功能封装在自己的类中。。。