我正在寻找一种方法来生成一个名为Contracts的对象列表。
在输入中,我有一个由ID, ContractName, Filename
组成的合同列表。我正在寻找一种方法来输出一个带有名称的Contracts列表,以及一个将收集Ids和FileName的IEnumerable<Documents> (ID, Filename)
字符串。
合同就像名字收集的许多文件一样。
我知道我可以使用Linq而且我必须使用groupby,而且我很难填充IEnumerable。
输入列表
ID, ContractName, FileName
01, Contract1, File 1
02, Contract1, File 2
03, Contract1, File 3
04, Contract2, File 4
05, Contract3, File 5
06, Contract3, File 6
07, Contract3, File 7
输出清单:
Contract 1, { {01, File 1},{02, File 2},{ 03, File 3} }
Contract 2, { {04, File 4}}
Contract 1, { {05, File 5},{06, File 6},{ 07, File 7} }
答案 0 :(得分:1)
您可以使用ToLookup
创建Lookup<k, v>
:
var contractNameLookup = contracts.ToLookup(c => c.ContractName);
现在,您可以轻松高效地查找属于名称的所有文件:
List<string> fileNamesOfContract = contractNameLookup["foo"]
.Select(c => c.Filename)
.ToList();
如果名称不在查找中,您将有一个空列表。
Lookup<TKey, TElement>
类似于Dictionary<TKey, TValue>
。该 区别在于Dictionary<TKey, TValue>
将键映射到单个 价值,而Lookup<TKey, TElement
&gt; 将密钥映射到集合 值强>
答案 1 :(得分:1)
问题有点不清楚,但基本上带有匹配对象的IEnumerable将是从IGrouping<TKey, TElement>
方法返回的GroupBy()
列表的每个元素的一部分。
示例:
var contractGroups = contracts.GroupBy(c => c.ContractName);
foreach(var contractGroup in contractGroups)
{
Console.WriteLine(contractGroup.Key + ":");
foreach(var contractFile in contractGroup)
{
Console.WriteLine("ID " + contractFile.ID + " = " + contractFile.Filename);
}
Console.WriteLine();
}
// ...or create more specific container objects for the result
var contractFiles = contractGroups.Select(cg => new { ContractName = cg.Key, Files = cg.Select(file => new { file.ID, file.Filename }) });