使用Linq中的分组创建字典(of Dictionary)

时间:2012-11-02 15:31:31

标签: c# .net vb.net linq

我知道我可以用循环来做这件事(事实上,我现在是,但我正在努力学习/提高我的Linq技能,我也希望它能提供更有效的解决方案。所以,这是我的情景:

说我有以下3个列表(我只是编写一个类似的例子,所以原谅它的愚蠢):

Dim lstTeachers as New List(of string)
Dim lstStudentsSex as New List(of string)
Dim lstStudentName as New List(of string)

例如,它们如下:

lstTeachers:     lstStudentsSex:     lstStudentName:
Teacher 1        Male                Whatever Name 1
Teacher 2        Female              Whatever Name 2 
Teacher 1        Female              Whatever Name 3
Teacher 1        Female              Whatever Name 4
Teacher 2        Male                Whatever Name 5
Teacher 3        Male                Whatever Name 6
Teacher 3        Female              Whatever Name 7
Teacher 1        Male                Whatever Name 8
Teacher 1        Female              Whatever Name 9
Teacher 2        Male                Whatever Name 10

每个列表中的每个条目与具有相同索引的其他条目匹配 - 基本上类似于数据表,只存储在单独的列表中。

现在,假设我想使用以下值创建以下结构:

Dim dictTeacherSexName as New Dictionary(Of String, Dictionary(Of String, List(of String)))

Dict1_Key:        Dict1_Value / Dict2_Key:         Dict2_Value:
Teacher 1         Male                             Whatever Name 1
                                                   Whatever Name 8
                  Female                           Whatever Name 3
                                                   Whatever Name 4
                                                   Whatever Name 9
Teacher 2 ...

......我希望这能解释我想要实现的目标。

现在,再一次,我知道这可能是一个愚蠢的想法,但我也问它,因为我想提高我的Linq技能 - 特别是Group By和多个选择仍然会吸引我,所以请帮助。

非常感谢!

4 个答案:

答案 0 :(得分:4)

这三个列表使事情变得有点困难,但并非不可能。您可以按照@fsimonazzi的建议先将列表压缩在一起,也可以将查询基于列表索引而不是列表条目本身。结果可能如下所示:

<子> (C#)

var result = Enumerable
    .Range(0, lstTeachers.Count)
    .GroupBy(i => lstTeachers[i])
    .ToDictionary(g => g.Key, g => g
        .GroupBy(i => lstStudentsSex[i])
        .ToDictionary(h => h.Key, h => h
            .Select(i => lstStudentName[i])
            .ToList()));

// result is Dictionary<string, Dictionary<string, List<string>>>

答案 1 :(得分:2)

使用离散的信息片段而不是带有Student实例的单个列表,这并不是很好。如果你想在这里使用group,你可能需要先将zip个集合放在一起,然后再使用三元组的一个枚举,然后开始对该枚举使用查询操作。

答案 2 :(得分:2)

这或多或少是Spender的解决方案,但这很有效。

在C#中

var dict = lstTeachers.Zip(lstStudentsSex, (teacher, sex) => new { teacher, sex })
    .Zip(lstStudentName, (x, student) => new { x.teacher, x.sex, student })
    .GroupBy(x => x.teacher)
    .ToDictionary(g => g.Key, g => g.GroupBy(x => x.sex)
        .ToDictionary(p => p.Key, p => p.Select(x => x.student)));

答案 3 :(得分:1)

<击> 我只有C#,而不是VB。提前道歉。

<击>

让我们首先制作一个包含属性teachersexname的匿名对象列表:

var singleList = lstTeachers
  .Zip(lstStudentsSex, (teacher, sex) => new {teacher, sex})
  .Zip(lstStudentName, (x,name) => new {x.teacher, x.sex, name})

现在我们可以把它变成字典词典:

singleList
  .GroupBy(x => x.teacher)
  .ToDictionary(
       g => g.Key, 
       g => g.ToDictionary(x => x.sex, x => x.name))

<击>

请参阅@ nawfal's获取我的代码的更正版本。