2015-11-19 36 views
0

我有這樣的對象結構:C#集團由幾個嵌套屬性和值列表

public class Root 
{ 
public int Value1; 
public int Value2; 
public List<NestedA> NestedAList; 
} 

public class NestedA 
{ 
public List<NestedB> NestedBList; 
public List<NestedC> NestedCList; 
} 

public class NestedB{ 
public int ValueB; 
public int ValueB2; 
} 

public class NestedC{ 
public int ValueC; 
public int ValueC2; 
} 

我需要使用所有的值從根類組根對象和它的嵌套的列表。 我一直在玩弄了一會兒,不能找出如何/或如果我可以聲明這樣做在一個組,或者什麼是最好的方式來acomplish這可能是。

編輯:我需要根性質,嵌套在一個屬性,嵌套在b屬性和生成的嵌套C屬性分組的項目。 所以它是有道理的:我的真實對象有更多的屬性,只顯示我需要分組的那些屬性,並且可以用作起始點。

在此先感謝。

如果我們有這個元素

Root 
Value1 = 1 
Value2 = 2 
NestedAList = [ 
    {NestedBList = [ 
     {ValueB=2, ValueB2=3} 
    ] 
    NestedCList = [ 
     {ValueC=5, ValueC2=11} 
    ]} 
] 

應該與這一個分組:

Root 
Value1 = 1 
Value2 = 2 
NestedAList = [ 
    {NestedBList = [ 
     {ValueB=2, ValueB2=3} 
    ] 
    NestedCList = [ 
     {ValueC=5, ValueC2=11} 
    ]} 
] 

但不是這一個:

Root 
Value1 = 1 
Value2 = 2 
NestedAList = [ 
    {NestedBList = [ 
     {ValueB=2, ValueB2=3}, { ValueB= 1, ValueB2=4} 
    ] 
    NestedCList = [ 
     {ValueC=5, ValueC2=11} 
    ]} 
] 
+4

可以請你告訴了簡單的輸入和輸出?你想完全按照哪個屬性進行分組?你想打開嵌套列表嗎?其不明確。 –

+0

我建議你看看這個問題。也許這是你需要.. http://stackoverflow.com/questions/5231845/c-sharp-linq-group-by-on-multiple-columns –

+0

什麼,一個是使用多列和選擇組進入一個新的,我需要使用列表值進行分組。但是,我嘗試使用一些想法進行分組,但無法使其工作。 –

回答

1

爲了完成這個任務,你可以覆蓋層次結構中每個類的Equals()GetHashCode()方法。這可能是有點棘手,例如,像這樣:

public class Root 
{ 
    public int Value1; 
    public int Value2; 
    public List<NestedA> NestedAList; 

    public override bool Equals(object obj) 
    { 
     Root other = obj as Root; 
     if (other == null) return false; 
     return this.Value1 == other.Value1 && this.Value2 == other.Value2 && this.NestedAList.SequenceEqual(other.NestedAList); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int hasha = 19; 
      foreach (NestedA na in NestedAList) 
      { 
       hasha = hasha * 31 + na.GetHashCode(); 
      } 

      return (Value1^Value1^hasha).GetHashCode(); 
     }    
    } 
} 

public class NestedA 
{ 
    public List<NestedB> NestedBList; 
    public List<NestedC> NestedCList; 

    public override bool Equals(object obj) 
    { 
     NestedA other = obj as NestedA; 
     if (other == null) return false; 

     return NestedBList.SequenceEqual(other.NestedBList) && NestedCList.SequenceEqual(other.NestedCList); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int hashb = 19; 
      foreach (NestedB nb in NestedBList) 
      { 
       hashb = hashb * 31 + nb.GetHashCode(); 
      } 
      int hashc = 19; 
      foreach (NestedC nc in NestedCList) 
      { 
       hashc = hashc * 31 + nc.GetHashCode(); 
      } 
      return (hashb^hashc).GetHashCode(); 
     }    
    } 
} 

public class NestedB{ 
    public int ValueB; 
    public int ValueB2; 

    public override bool Equals(object obj) 
    { 
     NestedB other = obj as NestedB; 
     if (other == null) return false; 
     return this.ValueB == other.ValueB && this.ValueB2 == other.ValueB2; 
    } 

    public override int GetHashCode() 
    { 
     return (ValueB^ValueB2).GetHashCode(); 
    } 
} 

public class NestedC{ 
    public int ValueC; 
    public int ValueC2; 

    public override bool Equals(object obj) 
    { 
     NestedC other = obj as NestedC; 
     if (other == null) return false; 
     return this.ValueC == other.ValueC && this.ValueC2 == other.ValueC2; 
    } 

    public override int GetHashCode() 
    { 
     return (ValueC^ValueC2).GetHashCode(); 
    } 
} 

之後,你可以很容易地選擇唯一根(每一個獨特的根代表一組):

roots.Distinct().ToList() 
使用 GoupBy()

相同的結果:

每個組中
roots.GroupBy(r => r).Select(g => g.First()).ToList() 

計數元素:

roots.GroupBy(r => r).Select(g => g.Count()) 

第一組中枚舉的元素:

roots.GroupBy(r => r).First().Select(g => g) 

如果你不關心的元素在列表順序,使用的Enumerable.All代替SequenceEqual

編輯:另外,在這種情況下,你必須改變哈希代碼生成alghoritm。例如,像這樣的:hashb = hashb + nb.GetHashCode() * 31;(約可能的算法here額外信息)

+0

我現在就是這樣,會嘗試這個解決方案,並讓你知道。 –

+0

感謝這使得它。不得不改變哈希代碼的生成,因爲我不關心列表中的元素順序,所以我以這種方式結束了生成代碼,例如:hashb = hashb + nb.GetHashCode()* 31 ;. –

+0

不客氣。根據你的評論,我已經更新了我的答案 –