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

时间:2012-11-06 20:15:17

标签: vb.net linq

几天前我通过this thread提出了一个几乎与此相同的问题并获得了很棒的回复 - 对我来说最重要的一课(除了答案本身)是为我的持有数据创建一个自定义对象。 那么,现在已经这样做了,我可以请各位专家向我展示最有效的Linq声明以满足我的要求吗?

我的情景如下:

假设我有以下持有类:

Public Class Class_Info
    Public Property Teacher As String
    Public Property Name As String
    Public Property Sex As String
End Class

然后,假设我在另一个模块中有以下内容:

Dim X as new list(of Class_Info)

列表中包含以下元素:

Element.Teacher:     Element.Sex:        Element.Name:
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创建它?

感谢!!!

1 个答案:

答案 0 :(得分:1)

它与上次相同,但不依赖索引,而是直接指向对象。

var result = X.GroupBy(i => i.Teacher)
     .ToDictionary(g => g.Key, g => g
         .GroupBy(i => i.Sex)
         .ToDictionary(h => h.Key, h => h
             .Select(i => i.Name)
             .ToList()));

您也可以使用ILookup进行清洁使用。您可以使用自定义类作为查找对象,但它需要实现IComparable。

class Program
{
    public static void Main()
    {
        var X = new List<Class_Info>();

        X.Add(new Class_Info { Teacher = "Teacher 1", Sex = "Male", Name = "Whatever Name 1" });
        X.Add(new Class_Info { Teacher = "Teacher 2", Sex = "Female", Name = "Whatever Name 2" });
        X.Add(new Class_Info { Teacher = "Teacher 1", Sex = "Female", Name = "Whatever Name 3" });
        X.Add(new Class_Info { Teacher = "Teacher 1", Sex = "Female", Name = "Whatever Name 4" });
        X.Add(new Class_Info { Teacher = "Teacher 2", Sex = "Male", Name = "Whatever Name 5" });
        X.Add(new Class_Info { Teacher = "Teacher 3", Sex = "Male", Name = "Whatever Name 6" });
        X.Add(new Class_Info { Teacher = "Teacher 3", Sex = "Female", Name = "Whatever Name 7" });
        X.Add(new Class_Info { Teacher = "Teacher 1", Sex = "Male", Name = "Whatever Name 8" });
        X.Add(new Class_Info { Teacher = "Teacher 1", Sex = "Female", Name = "Whatever Name 9" });
        X.Add(new Class_Info { Teacher = "Teacher 3", Sex = "Male", Name = "Whatever Name 10" });

        var result = X.ToLookup(key => new Tuple<string,string>(key.Teacher, key.Sex), value => value.Name);

        // Name is a IEnumerable<string> of all names who have "Teacher 1" and are Male.
        var name = result[new Tuple<string,string("Teacher 1","Male")];
    }

    public class Class_Info
    {
        public string Teacher;
        public string Name;
        public string Sex;
    }
}