2015-02-06 61 views
2

如何通過除這些對象的屬性之外的其他屬性對對象列表進行分組?我需要將List統計分組。列表中的每個對象都有屬性字符串Question,並且對於每個Question都有一些可能的答案,我希望將列表分組(每個組具有相同的可能答案),但這些可能的答案與Statistics類沒有直接關係。通過除這些對象的屬性之外的其他屬性對對象列表進行分組

我想要做這樣的事情:

var customGroups = from stat in statistics group stat by new { PossibleAnswers = questions.SingleOrDefault(q => q.Text == stat.Question).PossibleAnswers }; 
foreach (var group in customGroups) 
{ 
    StatisticsWithSamePossibleAnswers.Add(group.ToList()); 
} 

的代碼提供運行時異常:對象引用不設置到對象的實例。

那麼這樣做的好方法是什麼?我知道我總是可以使用嵌套的foreach循環,但是有什麼更明智的嗎?

類統計和問題是這樣的:

public class Statistics 
{ 
    public int ID { get; set; } 
    public int Year { get; set; } 
    public int Semester { get; set; } 
    public string Subject { get; set; } 
    public string Question { get; set; } 
    public bool IsAssociatedWithProfessor { get; set; } 
    public bool IsAssociatedWithAssistant { get; set; } 
    public string Answer { get; set; } 
    public int NumberOfAnswers { get; set; } 
    public double AnswerPercentage { get; set; } 
    public double? AM { get; set; } 
    public double? SD { get; set; } 
} 
public class Question 
{ 
    public int ID { get; set; } 
    public string Text { get; set; } 
    public bool IsAssociatedWithProfessor { get; set; } 
    public bool IsAssociatedWithAssistant { get; set; } 
    public virtual ICollection<PossibleAnswer> PossibleAnswers { get; set; } 
    public virtual ICollection<Results> Results { get; set; } 
} 
+1

你能提供一個像結構的小樣本嗎?我只是想確定我的理解正確 – CheGueVerra 2015-02-06 23:56:57

+0

目前,你的代碼正在拋出,因爲'questions'中沒有匹配的元素。但我正在爲一般情況尋找答案。 – recursive 2015-02-07 00:20:57

+0

我用一個Where替換了SingleOrDefault,並在最後註釋了這部分.PossibleAnswers,似乎正在工作,但SingleOrDefault我不明白爲什麼你正在使用它 – CheGueVerra 2015-02-07 00:26:14

回答

3

HashSet<T>可以使用正確的相等比較器進行分組。

var customGroups = statistics.GroupBy(
    stat => new HashSet<PossibleAnswer>(questions.Single(q => q.Text == stat.Question).PossibleAnswers), 
    HashSet<PossibleAnswer>.CreateSetComparer()); 

請注意,這忽略了答案順序和重複的答案。這也假定PossibleAnswer是默認等同的。

+0

一個很好的方法。它不太可能解決OP報告的錯誤,因爲'.Single()'會在找不到匹配問題時拋出異常。但是這可能是數據的問題,而不是代碼的問題。 – StriplingWarrior 2015-02-07 00:32:14

+0

@StriplingWarrior:這是真的,但一旦錯誤得到糾正,現有的代碼將無法按預期進行分組,因爲'List'不是可以等同的。 – recursive 2015-02-07 00:35:25

+0

https://msdn.microsoft.com/en-us/library/bb359438.aspx HashSet msdn – CheGueVerra 2015-02-07 00:37:40

2

爲了在group by查詢使用的東西爲關鍵,它必須是東西,可以是平等的,相比較。僅僅因爲它們具有相同的值,列表並不被視爲「相等」,因此您需要將可能的答案列表轉換爲更具可比性的列表。在下面的代碼示例中,我使用了string.Join()來產生一個以逗號分隔的答案字符串,但您可以根據需要調整它。還通過擺脫SingleOrDefault()

var customGroups = from stat in statistics 
    group stat by string.Join(", ", 
     from q in questions 
     where q.Text == stat.Question 
     select q.PossibleAnswers); 
foreach (var group in customGroups) 
{ 
    StatisticsWithSamePossibleAnswers.Add(group.ToList()); 
} 

注意我避免你正在運行到,當你打一個stat是沒有匹配的問題,並得到了一個空引用異常問題。相反,你應該得到一個空字符串來分組。

+0

是不是像這樣var var customList = from stat在統計中 \t \t \t \t group stat by new {PossibleAnswers = questions.Where(q => q.Text == stat.Question)}; – CheGueVerra 2015-02-07 00:28:43

+0

@CheGueVerra:不,因爲正如我上面所解釋的,'PossibleAnswers'對於每個'stat'都將是一個新的'IEnumerable <>',所以即使它們具有相同的可能答案,也不會將任何東西組合在一起。 – StriplingWarrior 2015-02-07 00:30:22

+0

我仍然在LinqPad上玩它,不知道我得到它全部 – CheGueVerra 2015-02-07 00:31:21

相關問題