2016-09-24 37 views
0

我有一個對象叫做模擬結果。使用linq計數組

public SimulationResult 
{ 
     public Horse Winner {get;set;} 
     public Horse Second {get;set;} 
     public Horse Third {get;set;} 
     public Horse Fourth {get;set;} 
    } 

    public Horse 
    { 
     public Guid Id{get;set;} 
    } 

因此,我有一個50000 SimulationResult的列表。我如何確定前50個最常見的結果。

我試過使用LINQ groupBy,但是horseId出現在每個對象中,並且它不允許多次出現一個值。

編輯 對不起,認爲很明顯。 所以我們共有8匹馬。說馬ID是1-8。因此,在仿真結果1

獲勝者是1,第二個是2,第三爲3,第四個爲4

在仿真結果2第一是5,第二個是6,第三是7,第四是8。

在仿真結果3首先是1,第二個是2,第三爲3,第四個爲4

所以結果集1和結果集3是相等的。所以在這個例子中,贏家1秒2 3 3 4 4是最常見的結果。

+2

我想你需要爲我們定義「最常見」? – TigOldBitties

+0

可以請你分享你的餐桌結構,並提供你想要的例子 –

+0

我編輯了這個問題。希望這更清楚。 – DidIReallyWriteThat

回答

1

簡單的回答你的問題:

class ExactResult { 
    public String CombinedId { get; set; } 
    public int Count { get; set; } 
} 
resultList.Select(l => { 
    var combinedId = l.Winner.Id.ToString() + l.Second.Id.ToString() + l.Third.ToString() + l.Fourth.ToString(); 
    return new ExactResult() { CombinedId = combinedId), Count = l.Count(c => c.Winner.Id.ToString() + c.Second.Id.ToString() + c.Third.ToString() + c.Fourth.ToString();)} 
}).OrderByDescending(e => e.Count).Take(50) 

答案是沒有意義的,雖然。如果你真的想要的是從一堆結果中最有可能的4個獲勝者,那麼這不是解決問題的方法。這將只顯示與同樣4個獲獎者的最佳結果。 您可能要查找的是統計分析或可能傳播。無論如何,事情比你真正要問的要複雜得多。

+0

我正在尋找我所描述的(很差)。我想出了一個獲得最常見的4個獲勝者的方法,但我需要最精確的排名前4位。 – DidIReallyWriteThat

1

也許這是你在找什麼:

var q = (from x in mySimulationResultList 
     group x by x into g 
     let count = g.Count() 
     orderby count descending 
     select new { Value = g.Key, Count = count }).Take(50); 

foreach (var x in q) 
{ 
    Console.WriteLine($"Value: {x.Value.ToString()} Count: {x.Count}"); 
} 

如果您想要進行有意義的輸出Console.WriteLine你需要重寫ToStringHorseSimulationResult

必須覆蓋EqualsGetHashCodeSimulationResult,如下所示:

public override bool Equals(object obj) 
{ 
    SimulationResult simResult = obj as SimulationResult; 
    if (simResult != null) 
    { 
     if (Winner == simResult.Winner 
      && Second == simResult.Second 
      && Third == simResult.Third 
      && Fourth == simResult.Fourth) 
     { 
      return true; 
     } 
    } 
    return false; 
} 
public override int GetHashCode() 
{ 
    int hash = 12; 
    hash = hash * 5 + Winner.GetHashCode(); 
    hash = hash * 5 + Second.GetHashCode(); 
    hash = hash * 5 + Third.GetHashCode(); 
    hash = hash * 5 + Fourth.GetHashCode(); 
    return hash; 
} 

源頭here(由查詢組)和here(針對海誓山盟比較對象)

3

我試圖使用LINQ GROUPBY但horseId出現在每個對象和它不允許一個值的多次出現。

如果你的意思是使用在Grouping by Composite Keys解釋,雖然大部分的時間我們可以讓編譯器推斷出我們的名字,我們總能(這裏有必要)匿名類型明確指定:

var topResults = simulationResults 
    .GroupBy(r => new 
    { 
     WinnerId = r.Winner.Id, 
     SecondId = r.Second.Id, 
     ThirdId = r.Third.Id, 
     FourthId = r.Fourth.Id, 
    }) 
    .OrderByDescending(g => g.Count()) 
    .Select(g => g.First()) // or new { Result = g.First(), Count = g.Count() } if you need the count 
    .Take(50) 
    .ToList(); 
+0

這是美麗的,完美的作品。你有沒有提供這方面的資料,或只是很多LINQ練習? – DidIReallyWriteThat

+1

一個來源當然是答案中的鏈接,另一個來源是[匿名類型(C#編程指南)(https://msdn.microsoft.com/en-us/library/bb397696.aspx),然後當然是經驗來與大量的實驗和SO難題:) –