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
}
}