我有一个名为模拟结果的对象。
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出现在每个对象中,并且它不允许多次出现一个值。
EDIT 对不起,以为很清楚。 所以我们共有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是最常见的结果。
答案 0 :(得分: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();
答案 1 :(得分: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名获胜者,那么这不是解决问题的方法。这将与EXACT相同的4位获胜者展示最多的结果。 您可能正在寻找的是统计分析或传播。无论如何,事情比你实际要问的更复杂。
答案 2 :(得分: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
提供有意义的输出,则需要覆盖ToString
和Horse
的{{1}}
您必须覆盖SimulationResult
的{{1}}和Equals
,如下所示:
GetHashCode