使用linq计数组

本文关键字:数组 linq 使用 | 更新日期: 2023-09-27 18:08:33

我有一个对象叫做仿真结果。

 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第四4是最常见的结果。

使用linq计数组

我尝试使用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个获胜者最多的结果。你想要的可能是统计分析或者传播。总之事情比你实际问的要复杂得多

也许这就是你要找的:

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

你必须覆盖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;
}

这里的源(按查询分组)和这里的源(相互比较对象)