2012-11-06 30 views
0

幾天前我通過this thread問了一個幾乎與此相同的問題,並得到了令人敬畏的答覆 - 對我來說最重要的一課(除了答案本身)是爲我的持有數據創建一個自定義對象。 因此,現在我已經完成了這項工作,請問您的專家請向我展示最有效的Linq聲明以滿足我的要求?在Linq中使用分組創建字典(第2部分)

我的情況如下:

假設我有以下控股類:

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

它與上次相同,但不是依靠索引,而是直接指向對象。

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; 
    } 
} 
+0

這的確很有意義! - 謝謝!!! - Linq仍然像打敗戰士一樣擊敗我! –

+0

感謝您的詳細示例...快速的問題 - 查找是否提供比字典更好的功能?有沒有更好的理由來使用它呢?非常感謝你這樣做! –

+1

詞典通常只允許每個鍵一個值,但在字典方法中,您正在存儲列表作爲基準項。 ILookup爲您包裝所有功能。你可以將'ILookup '想象成'IDictonary > –