如何使用C#中的列表构建包含带有groupBy的列表的Object列表?

时间:2016-09-06 12:05:34

标签: c# linq

我正在寻找一种方法来生成一个名为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} }

2 个答案:

答案 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 }) });