0

私は数日前にこのスレッドを介してこれとほぼ同じ質問をし、素晴らしい回答を得ました - 私にとって最大の教訓 (回答自体は別として) は、保持しているデータ用のカスタム オブジェクトを作成することでした。それで、今それを行ったので、専門家に依頼して、私の要件を満たす最も効率的な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を介してそれを作成するにはどうすればよいですか?

ありがとう!!!

4

1 に答える 1

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;
    }
}
于 2012-11-06T20:45:55.697 に答える