C# 创建一个包含多个键的字典,并使用其中一个键获取值

C# 创建一个包含多个键的字典,并使用其中一个键获取值,c#,dictionary,data-structures,collections,C#,Dictionary,Data Structures,Collections,我想创建一个具有多个键的字典,当我只想使用一个或多个键获取值时 我试过: Dictionary<Tuple<int, string>, string> dictionary = new Dictionary<Tuple<int, string>, string>(); var Key =new Tuple<int,string>(1,"I1"); var Valu

我想创建一个具有多个键的
字典
,当我只想使用一个或多个键获取值时

我试过:

        Dictionary<Tuple<int, string>, string> dictionary = new Dictionary<Tuple<int, string>, string>();

        var Key   =new Tuple<int,string>(1,"I1");
        var Value = "this is a value";

        dictionary.Add(Key, Value);
MessageBox.Show($"{dictionary[new Tuple<int, string>(1,"I1")]}");
但是当我尝试使用像这样的一个键获取值时

MessageBox.Show($"{dictionary[new Tuple<int, string>(1,"")]}");
MessageBox.Show($“{dictionary[新元组(1)”);
我得到了一个错误,我知道这个错误是因为
字典
需要完整的exist键来返回一个值


因此,请任何人都知道如何创建一个包含多个
键的
字典
,并且在仅使用一个多个检索值时,所有

在.NET中的字典的查找时间预计接近O(1)次。为了实现这一点,它们使用键对象的
GetHashCode()
Equals()
方法。生成的哈希代码用于将字典的内容划分为多个分区。当您查找一个项时,分区将使用哈希代码标识,该分区中具有匹配哈希代码*的所有项将与您正在使用
Equals()
方法查找的键进行比较

在这里,您试图为每个对象创建一个具有两个键的字典。您正在使用一个
元组来制作一个键。
元组的
GetHashCode()
结果基于它的两个值,因此,如果只想按键的一半查找值,则字典的性能将丢失。您需要通读整本词典,比较每个单独的条目,使其比列表更好

一种解决方案是创建一个包含字符串->int键查找的字典,然后另一个字典就是int->字符串。这在使用字符串键时需要两次查找,但可能是一个好的解决方案

例如:

Dictionary<string, int> stringKeyToIntKey = new Dictionary<string, int>();
Dictionary<int, string> intKeyDict = new Dictionary<int, string>();

intKeyDict[1] = "Test";
stringKeyToIntKey["I1"] = 1;

Console.WriteLine(intKeyDict[1]);
Console.WriteLine(intKeyDict[stringKeyToIntKey["I1"]]);
Dictionary<string, string> stringKeyDict = new Dictionary<string, string>();
Dictionary<int, string> intKeyDict = new Dictionary<int, string>();

stringKeyDict["I1"] = "hello";
intKeyDict[1] = "hello";

Console.WriteLine(stringKeyDict["I1"]);
Console.WriteLine(intKeyDict[1]);
您可以包装TryGetValue,使生活更轻松:

public bool TryGetValue(string stringKey, out string value)
{
    value = null;
    return stringKeyToIntKey.TryGetValue(stringKey, out int intKey) && intKeyDict.TryGetValue(intKey, out value);
}
删除将如下所示:

public void AddEntry(int intKey, string stringKey, string value)
{
    intKeyDict[intKey] = value;
    stringKeyToIntKey[stringKey] = intKey;
}
public void DeleteEntry(string stringKey)
{
    if (stringKeyToIntKey.TryGetValue(stringKey, out int intKey))
    {
        intKeyDict.Remove(intKey);
        stringKeyToIntKey.Remove(stringKey);
    }
}
dictionary.Where(kvp=>kvp.Key.Contains($"{x}:"))
您必须确保同时从两个词典中添加和删除项。将项添加到
intKey
时,需要将相应的键映射添加到
stringKeyToIntKey

或者,您可以有两个字典:一个带有字符串键,另一个带有int键,每个字典都有相同的值。同样,您必须同时添加和删除项目,并且还必须同时更新这两个项目中的值

例如:

Dictionary<string, int> stringKeyToIntKey = new Dictionary<string, int>();
Dictionary<int, string> intKeyDict = new Dictionary<int, string>();

intKeyDict[1] = "Test";
stringKeyToIntKey["I1"] = 1;

Console.WriteLine(intKeyDict[1]);
Console.WriteLine(intKeyDict[stringKeyToIntKey["I1"]]);
Dictionary<string, string> stringKeyDict = new Dictionary<string, string>();
Dictionary<int, string> intKeyDict = new Dictionary<int, string>();

stringKeyDict["I1"] = "hello";
intKeyDict[1] = "hello";

Console.WriteLine(stringKeyDict["I1"]);
Console.WriteLine(intKeyDict[1]);
Dictionary stringKeyDict=newdictionary();
Dictionary intKeyDict=新字典();
stringKeyDict[“I1”]=“你好”;
intKeyDict[1]=“你好”;
控制台写入线(stringKeyDict[“I1”]);
Console.WriteLine(intKeyDict[1]);
这是我最喜欢的方法,其中值是类实例,因为两个字典都会为我的项目引用相同的类实例,因此对这些实例的属性的更改将反映在这两个字典中。但是,对于字符串,第一个选项可能更好


*哈希代码不是唯一的,多个对象可能具有相同的哈希代码,即使它们的值不相同

您可以使用字符串作为字典键。假设您想从
int x=5
string y=“str”创建一个键。
您可以使用一些分隔符对它们进行合并和拆分,并创建如下键:

public void AddEntry(int intKey, string stringKey, string value)
{
    intKeyDict[intKey] = value;
    stringKeyToIntKey[stringKey] = intKey;
}
public void DeleteEntry(string stringKey)
{
    if (stringKeyToIntKey.TryGetValue(stringKey, out int intKey))
    {
        intKeyDict.Remove(intKey);
        stringKeyToIntKey.Remove(stringKey);
    }
}
dictionary.Where(kvp=>kvp.Key.Contains($"{x}:"))
string key=$“{x}:{y}”

假设你只想通过x得到元素。你可以这样写:

public void AddEntry(int intKey, string stringKey, string value)
{
    intKeyDict[intKey] = value;
    stringKeyToIntKey[stringKey] = intKey;
}
public void DeleteEntry(string stringKey)
{
    if (stringKeyToIntKey.TryGetValue(stringKey, out int intKey))
    {
        intKeyDict.Remove(intKey);
        stringKeyToIntKey.Remove(stringKey);
    }
}
dictionary.Where(kvp=>kvp.Key.Contains($"{x}:"))

当然,它不会在O(1)时间内给出元素(它会在O(n)时间内给出元素),但它会起作用。如果您只想通过x在O(1)时间内获取元素,我不确定使用一个字典是否可行。

这里的问题可能是数据冗余吗?你觉得怎么样,先生?我会在我写的答案中提到。我在等,先生,真的很感激,非常感谢你可能会遇到一个问题,你可以为你的钥匙获得不止一个价值provide@MohamedMoselhy我相信所有的钥匙都不是复制品我很感激你John,让我对你的时间和努力以及你伟大的回答表示衷心的感谢,但是,先生,我还有一件事要完成我的理解,那就是当我有了所有的钥匙都是字符串的时候?你对解决这个案子有什么想法?谢谢again@XDev如果您的所有键都是字符串,那么您可能只需按照TaW的建议为每个值向同一字典添加两个条目(每个键一个条目)。与我的第二个建议相同的要求也适用,因为您仍将处理两个条目,但如果您没有任何关键冲突,则应该可以使用。@John请接受我的尊重,非常感谢您的帮助。字典不是这样工作的:我已更新了我的问题。谢谢你,约翰纠正了我的回答