2016-09-24 2 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が各オブジェクトに表示され、1つの値が複数回出現することはできません。

EDIT 申し訳ありませんが、それは明らかでした。 私たちは合計8頭の馬を持っています。馬のIDは1-8だと言います。

そこでシミュレーション結果1における勝者は、第2、第3、1 2 3であり、第四の第二第三は、第2の5シミュレーション結果で4

第7れる6である8。シミュレーション結果第3に

は、第二の、1 2、第3、第だから1結果セット3が等しい結果セット4

あります。このサンプルでは、​​勝者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あなたがHorseSimulationResult

ためToStringをオーバーライドする必要がありますあなたがEqualsGetHashCode用をオーバーライドする必要がありますため、意味のある出力をしたい場合SimulationResult、このようなもの:

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

1つのソースはもちろん、答えのリンクです。もう1つは[Anonymous Types(C#プログラミングガイド)(https://msdn.microsoft.com/en-us/library/bb397696.aspx)です。多くの実験やSOのパズルに来る経験:) –