使用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 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
有意义的输出,您需要为Horse
和SimulationResult
覆盖ToString
你必须覆盖Equals
和GetHashCode
为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;
}
这里的源(按查询分组)和这里的源(相互比较对象)