将带有 List 的字典转换为 IEnumerable
Convert dictionary with List to IEnumerable
我有字典:
Dictionary<String, List<Foo>> test = new Dictionary<String, List<Foo>>();
然后我填充这个字典,因此我需要这个列表以便我可以调用 Add()。我的问题是函数需要 return:
Dictionary<String, IEnumerable<Foo>>
有没有简单的方法可以做到这一点,而不用做显而易见的事情并循环遍历我原来的字典并手动完成?
return dictionary.ToDictionary(x => x.Key,x => x.Value.AsEnumerable())
使用 List<Foo>
添加内容比使用 Dictionary<String, IEnumerable<Foo>>
更高效、更容易。这没问题,因为 List<Foo>
实现了 IEnumerable<Foo>
,甚至不需要转换。
所以像这样(伪代码):
var test = new Dictionary<String, IEnumerable<Foo>>();
foreach(var x in something)
{
var list = new List<Foo>();
foreach(var y in x.SomeCollection)
list.Add(y.SomeProperty);
test.Add(x.KeyProperty, list); // works since List<T> is also an IEnumerable<T>
}
我也尝试了这条路线,将 Dictionary<string, List<Foo>>
转换为 ReadOnlyDictionary<string, IEnumerable<Foo>>
。当我试图转换为只读字典时,将 List
转换为 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<Foo>
的出现让您认为这是只读且安全的,但实际上并非如此。看完问题 LINQ Convert Dictionary to Lookup 后,Lookup
对象更合适,因为它允许您:
将一个键与多个值相关联
您不能用新值覆盖键
// This results in a compiler error
lookUp["foo"] = new List<Foo>() { ... };
"multiple values"已经定义为IEnumerable<T>
您仍然可以使用相同的外循环和内循环算法来提取单个值:
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>>
转换为 ILookup<string, Foo>
这是一个快速的双线:
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<string, IEnumerable<Foo>>
:
相同的两步循环
foreach (IGrouping<string, Foo> grouping in lookup)
{
string key = grouping.Key;
foreach (Foo foo in grouping)
{
// Do stuff with key and foo
}
}
来源:LINQ Convert Dictionary to Lookup
转换为另一个具有 IEnumerable 值的字典就像试图将方钉塞入圆孔。更合适、更安全的方法(从面向对象的角度来看)是将 read/write 字典转换为查找。这为您提供了只读对象的真正预期安全性(Foo
项除外,它们可能不是不可变的)。
我什至可以说,大多数情况下,当使用 ReadOnlyDictionary
时,您可以使用 ILookup
并获得相同的功能。
我有字典:
Dictionary<String, List<Foo>> test = new Dictionary<String, List<Foo>>();
然后我填充这个字典,因此我需要这个列表以便我可以调用 Add()。我的问题是函数需要 return:
Dictionary<String, IEnumerable<Foo>>
有没有简单的方法可以做到这一点,而不用做显而易见的事情并循环遍历我原来的字典并手动完成?
return dictionary.ToDictionary(x => x.Key,x => x.Value.AsEnumerable())
使用 List<Foo>
添加内容比使用 Dictionary<String, IEnumerable<Foo>>
更高效、更容易。这没问题,因为 List<Foo>
实现了 IEnumerable<Foo>
,甚至不需要转换。
所以像这样(伪代码):
var test = new Dictionary<String, IEnumerable<Foo>>();
foreach(var x in something)
{
var list = new List<Foo>();
foreach(var y in x.SomeCollection)
list.Add(y.SomeProperty);
test.Add(x.KeyProperty, list); // works since List<T> is also an IEnumerable<T>
}
我也尝试了这条路线,将 Dictionary<string, List<Foo>>
转换为 ReadOnlyDictionary<string, IEnumerable<Foo>>
。当我试图转换为只读字典时,将 List
转换为 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<Foo>
的出现让您认为这是只读且安全的,但实际上并非如此。看完问题 LINQ Convert Dictionary to Lookup 后,Lookup
对象更合适,因为它允许您:
将一个键与多个值相关联
您不能用新值覆盖键
// This results in a compiler error lookUp["foo"] = new List<Foo>() { ... };
"multiple values"已经定义为
IEnumerable<T>
您仍然可以使用相同的外循环和内循环算法来提取单个值:
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>>
转换为 ILookup<string, Foo>
这是一个快速的双线:
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<string, IEnumerable<Foo>>
:
foreach (IGrouping<string, Foo> grouping in lookup)
{
string key = grouping.Key;
foreach (Foo foo in grouping)
{
// Do stuff with key and foo
}
}
来源:LINQ Convert Dictionary to Lookup
转换为另一个具有 IEnumerable 值的字典就像试图将方钉塞入圆孔。更合适、更安全的方法(从面向对象的角度来看)是将 read/write 字典转换为查找。这为您提供了只读对象的真正预期安全性(Foo
项除外,它们可能不是不可变的)。
我什至可以说,大多数情况下,当使用 ReadOnlyDictionary
时,您可以使用 ILookup
并获得相同的功能。