简体   繁体   English

如何在C#中检查字典中字典的键是否存在

[英]how to check key existence for dictionary within a dictionary in C#

In below code, how can I check key existence for dictionary within a dictionary? 在下面的代码中,如何检查字典中字典的键是否存在?

Current execution throws key existence error. 当前执行抛出键存在错误。

Output, For Key "a", another key "X" with both values 1 and 2 输出,对于键“ a”,另一个键“ X”的值分别为1和2

Do we have any better collection for this? 我们为此有更好的收藏吗?

 var data = new Dictionary<string, Dictionary<string, object>>();

        foreach (var j in GetTopData())
        {
            foreach (var p in BottomData())
            {
                if (data.Keys.Contains(j.ToString()))
                {
                    data[j].Add(p.Name, p.Value);
                }
                else
                {
                    data.Add(j, new Dictionary<string, object> { { p.Name, p.Value } });
                }
            }
        }

Here are the data classes, 这是数据类,

private static List<TempData> BottomData()
    {
        return new List<TempData>
        {
            new TempData{ Name="X", Value=1},
            new TempData{ Name="X", Value=2}
        };
    }

    private static List<string> GetTopData()
    {
        return new List<string> { "a"};
    }

public class TempData
{
    public string Name { get; set; }
    public object Value { get; set; }
}

Your code could be simplified to: 您的代码可以简化为:

        var data = new Dictionary<string, Dictionary<string, List<object>>>();

        foreach (var j in GetTopData())
        {
            foreach (var p in BottomData())
            {
                Dictionary<string, List<object>> values;
                var existed = data.TryGetValue(j, out values);

                if (!existed)
                    values = new Dictionary<string, List<object>>();

                List<Object> list;

                var existed2 = values.TryGetValue(p.Name, out list);
                if (!existed2)
                    list = new List<object>();

                list.Add(p.Value);

                if (!existed)
                    data.Add(j, values);

                if (!existed2)
                    values.Add(p.Name, list);
            }
        }

You'll need to check for existing data in both of the dictionaries. 您需要检查两个字典中的现有数据。 Currently you are checking existence in just one dictionary: 目前,您只在检查一本字典中的存在性:

var data = new Dictionary<string, Dictionary<string, object>>();

            foreach (var j in GetTopData())
            {
                foreach (var p in BottomData())
                {
                    if(data.ContainsKey(j.ToString()))
                    {
                        var mydict = data[j.ToString()];
                        if (!mydict.ContainsKey(p.Name))
                            data[j].Add(p.Name, p.Value);
                    }
                    else
                    {
                        data.Add(j, new Dictionary<string, object> { { p.Name, p.Value } });
                    }
                }
            }

Because you need one key to contain multiple values, Dictionary<string, Dictionary<string, object>> will not work for you (it allows only 1 value for particular key). 因为您需要一个键来包含多个值,所以Dictionary<string, Dictionary<string, object>>对您不起作用(特定键只允许使用1个值)。 You can use Dictionary<string, Dictionary<string, List<object>>> , but it is hard to read and difficult to work with. 您可以使用Dictionary<string, Dictionary<string, List<object>>> ,但是它很难阅读且难以使用。 So I thing it is better to use Dictionary, where both keys are combined into one as shown bellow in CombinedKey class (in C# 7.0, ValueTuple<string, string> will work too): 因此,我觉得最好使用Dictionary,将两个键组合为一个,如CombinedKey类中所示(在C#7.0中, ValueTuple<string, string>也可以使用):

public class CombinedKey
{
    public string Key1;
    public string Key2;

    // It is necessary to override Equals and GetHashCode to make
    // it work properly as a dictionary key.
    public override bool Equals(object obj)
    {
        var otherCombinedKey = obj as CombinedKey;

        return otherCombinedKey != null
            && otherCombinedKey.Key1 == this.Key1
            && otherCombinedKey.Key2 == this.Key2;
    }

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

Then use it this way: 然后以这种方式使用它:

Dictionary<CombinedKey, List<object>> data = new Dictionary<CombinedKey, List<object>>();

foreach (var j in GetTopData())
{
    foreach (var p in BottomData())
    {
        var key = new CombinedKey() { Key1 = j, Key2 = p.Name };
        List<object> list;
        if(!data.TryGetValue(key, out list))
        {
            data[key] = list = new List<object>();
        }
        list.Add(p.Value);
    }
}

If your data are immutable, you could also use Lookup<CombinedKey, object> class instead. 如果您的数据是不可变的,则还可以使用Lookup<CombinedKey, object>类。

Answer to your question how to check key existence for dictionary within a dictionary in C# : 回答您的问题, 如何在C#中检查字典中字典的键是否存在

You can check this by using Linq like this example : 您可以使用Linq进行检查,例如以下示例

bool keyExistance = data.Any(x=>x.Value.ContainsKey(keyTocheck));

But before that you have to fix the errors in your code. 但是在此之前,您必须修复代码中的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM