C# 将带有列表的字典转换为IEnumerable

C# 将带有列表的字典转换为IEnumerable,c#,dictionary,ienumerable,C#,Dictionary,Ienumerable,我有一本字典: Dictionary<String, List<Foo>> test = new Dictionary<String, List<Foo>>(); 字典测试=新建字典(); 然后我填充这个字典,因此我需要这个列表,以便调用Add()。我的问题是函数需要返回: Dictionary<String, IEnumerable<Foo>> 字典 有没有什么简单的方法可以做到这一点,而不必通过我的原始词典进行明

我有一本字典:

Dictionary<String, List<Foo>> test = new Dictionary<String, List<Foo>>();
字典测试=新建字典();
然后我填充这个字典,因此我需要这个列表,以便调用Add()。我的问题是函数需要返回:

Dictionary<String, IEnumerable<Foo>>
字典

有没有什么简单的方法可以做到这一点,而不必通过我的原始词典进行明显的循环并手动执行?

使用
列表添加内容,但将其添加到
词典中,这样会更高效、更容易。这没有问题,因为
List
实现了
IEnumerable
,甚至不需要强制转换

return dictionary.ToDictionary(x => x.Key,x => x.Value.AsEnumerable())
类似这样的东西(伪代码):

var test=newdictionary();
foreach(某物中的var x)
{
var list=新列表();
foreach(x.SomeCollection中的变量y)
列表。添加(y.SomeProperty);
test.Add(x.KeyProperty,list);//因为list也是一个IEnumerable而起作用
}

我也尝试了这种方法,将
字典转换成
只读字典。当我试图转换为只读词典时,将
列表
转换为
IEnumerable
的全部目的是创建一个只读集合。OP方法的问题是:

Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>();

errors["foo"] = new List<string>() { "You can't do this" };

Dictionary<string, IEnumerable<string>> readOnlyErrors = // convert errors...

readOnlyErrors["foo"] = new List<string>() { "I'm not actually read-only!" };
  • “多个值”已定义为
    IEnumerable

  • 您仍然可以使用相同的外循环和内循环算法来提取单个值:

    ILookup<string, string> lookup = // Convert to lookup
    
    foreach (IGrouping<string, string> grouping in lookup)
    {
        Console.WriteLine(grouping.Key + ":");
    
        foreach (string item in grouping)
        {
            Console.WriteLine("    item: " + item);
        }
    }
    
    ILookup lookup=//转换为查找
    foreach(查找中的i分组)
    {
    Console.WriteLine(grouping.Key+“:”);
    foreach(分组中的字符串项)
    {
    Console.WriteLine(“项:+项”);
    }
    }
    
  • Dictionary
    转换为
    ILookup
    这是一个快速的两行:

    Dictionary<string, List<Foo>> foos = // Create and populate 'foos'
    
    ILookup<string, Foo> lookup = foos.SelectMany(item => item.Value, Tuple.Create)
                                      .ToLookup(p => p.Item1.Key, p => p.Item2);
    
    Dictionary foos=//创建并填充“foos”
    ILookup lookup=foos.SelectMany(item=>item.Value,Tuple.Create)
    .ToLookup(p=>p.Item1.Key,p=>p.Item2);
    
    现在,您可以使用与
    字典相同的两步循环:

    foreach(查找中的i分组)
    {
    string key=grouping.key;
    foreach(分组中的Foo-Foo)
    {
    //用key和foo做一些事情
    }
    }
    
    资料来源:

    转换到另一本具有IEnumerable值的词典就像试图将一个方形的钉子塞进一个圆孔。从面向对象的角度来看,更合适、更安全的方法是将读/写字典转换为查找。这为您提供了只读对象的真正预期安全性(除了
    Foo
    项,它可能不是不变的)


    我甚至可以说,在大多数情况下,当使用
    ReadOnlyDictionary
    时,您可以使用
    ILookup
    并获得相同的功能。

    但是它通过循环原始字典来创建一个新字典,这是OP想要避免的。使用
    列表
    添加内容,但将其添加到
    字典
    中,也更高效、更容易。这没问题,因为
    List
    实现了
    IEnumerable
    ,甚至不需要强制转换。@TimSchmelter这是我想要的最终结果。如果你重新格式化成一个答案,我会标记为正确。谢谢。您是否考虑过改用查找?这通常是处理这类事情的一种更干净的方法。你为什么不首先使用
    字典
    ?如何填充它?也许您可以使用与Selman使用的类似的
    进行编辑,但首先是在填充时。如果不发布大量代码,就有点难以解释。我有两个不同的源,我用它们执行一些计算,然后创建一个新的对象,在本例中是Foo来存储结果。@DasDave:您应该看看一个可以从
    ToLookup
    获得的类,它是一个非常好的类,类似于字典。但是它的键不需要是唯一的,也不需要存在,并且值隐式地是一个
    IEnumerable
    (如果键不存在,则为空)。@DasDave:此外,如果您想使用
    添加
    并最终通过
    dict.Add(“foo”,List)将其添加到
    字典中,则始终可以使用
    列表
    因为
    列表实现了
    IEnumerable
    ILookup<string, string> lookup = // Convert to lookup
    
    foreach (IGrouping<string, string> grouping in lookup)
    {
        Console.WriteLine(grouping.Key + ":");
    
        foreach (string item in grouping)
        {
            Console.WriteLine("    item: " + item);
        }
    }
    
    Dictionary<string, List<Foo>> foos = // Create and populate 'foos'
    
    ILookup<string, Foo> lookup = foos.SelectMany(item => item.Value, Tuple.Create)
                                      .ToLookup(p => p.Item1.Key, p => p.Item2);
    
    foreach (IGrouping<string, Foo> grouping in lookup)
    {
        string key = grouping.Key;
    
        foreach (Foo foo in grouping)
        {
            // Do stuff with key and foo
        }
    }