将List<MyObject>转换为Dictionary<obj.string, List<obj.ID>>

31

我想将一个对象列表转换为字典,其中键是对象中的一个字段,值是匹配该键的不同字段在对象中的列表。目前我可以通过循环来实现这一点,但我觉得应该能够用LINQ来完成,而不必编写循环。我考虑使用GroupByToDictionary的组合,但到目前为止未成功。

这是我现在的做法:

var samplesWithSpecificResult = new Dictionary<string, List<int>>();
foreach(var sample in sampleList)
{
    List<int> sampleIDs = null;
    if (samplesWithSpecificResult.TryGetValue(sample.ResultString, out sampleIDs))
    {
        sampleIDs.Add(sample.ID);
        continue;
    }
    sampleIDs = new List<int>();
    sampleIDs.Add(sample.ID);
    samplesWithSpecificResult.Add(sample.ResultString, sampleIDs);
}

我使用.GroupBy().ToDictionay()得到的最远结果是 Dictionary<sample.ResultString, List<sample>>

欢迎任何帮助。


学会爱 Lookup - Mark Peters
4个回答

59

尝试以下操作

var dictionary = sampleList
    .GroupBy(x => x.ResultString, x => x.ID)
    .ToDictionary(x => x.Key, x => x.ToList());
GroupBy子句将按其ResultString成员对列表中的每个Sample实例进行分组,但它将仅保留每个示例的Id部分。这意味着每个元素都是一个IGrouping<string, int>

ToDictionary部分使用IGrouping<string, int>Key作为字典键。IGrouping<string, int>实现了IEnumerable<int>,因此我们可以通过调用ToList将该示例的Id集合转换为List<int>,这将成为给定Key的字典中的Value


非常感谢您的回答!通过试错来弄清那些细节需要花费一些时间。 - Martin Nilsson

4

是的,非常简单。关键在于,当你对 IEnumerable<T> 进行 GroupBy 操作时,每个“组”也同样实现了 IEnumerable<T> 接口(这就是为什么我可以在下面使用 g.Select,并使用一个公共键投影原序列的元素):

var dictionary =
     sampleList.GroupBy(x => x.ResultString)
               .ToDictionary(
                   g => g.Key,
                   g => g.Select(x => x.ID).ToList()
     );

看,sampleList.GroupBy(x => x.ResultString) 的结果是一个 IEnumerable<IGrouping<string, Sample>>,而 IGrouping<T, U> 实现了 IEnumerable<U>,所以每个分组实际上都是具有相同键的 Sample 序列!


3
Dictionary<string, List<int>> resultDictionary = 
(
  from sample in sampleList
  group sample.ID by sample.ResultString
).ToDictionary(g => g.Key, g => g.ToList());

您或许考虑使用查找表而不是列表的字典。
ILookup<string, int> idLookup = sampleList.ToLookup(
  sample => sample.ResultString,
  sample => sample.ID
);

使用方法如下
foreach(IGrouping<string, int> group in idLookup)
{
  string resultString = group.Key;
  List<int> ids = group.ToList();
  //do something with them.
}

//and

List<int> ids = idLookup[resultString].ToList();

查找是一个好主意,我一定会尝试一下。谢谢! - Marcus

1
var samplesWithSpecificResult =
    sampleList.GroupBy(s => s.ResultString)
              .ToDictionary(g => g.Key, g => g.Select(s => s.ID).ToList());

我们在这里做的是根据它们的ResultString对样本进行分组--这将它们放入一个IGrouping<string, Sample>中。然后,我们将IGrouping集合投影到字典中,使用每个IGroupingKey作为字典键,并枚举每个分组(IGrouping<string, Sample>也是一个IEnumerable<Sample>)来选择每个样本的ID以制作字典值的列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接