簡體   English   中英

使用linq計數組

[英]Count groups using 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 3第四4是最常見的結果。

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

如果您是按照“ 按組合鍵分組”中的說明使用匿名類型,盡管大多數時候我們可以讓編譯器推斷我們的名字,但我們始終可以(在這里有必要)明確指定它們:

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();

您問題的最簡單答案:

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位獲獎者的最多結果。 您可能正在尋找的是統計分析或傳播。 無論如何,事情要比您實際要求的要復雜。

也許這就是您想要的:

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

您必須為SimulationResult覆蓋EqualsGetHashCode ,如下所示:

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

此處 (按查詢分組)和此處 (將對象相互比較)的來源

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM