获得Linq中元素出现次数的最大值
本文关键字:最大值 Linq 元素 获得 | 更新日期: 2023-09-27 18:07:11
大家好,我有两个类,我将其命名为A和B
A是一个列表,每个A元素都有一个B元素的列表。元素的类型为
我想通过在B元素列表中出现来得到一个B元素
var listB = A
.SelectMany(a => a.B);
var listBId = listB
.Where(b => b.Type == SelectedType)
.Select(b => b.Id);
var IdMaxoccur = listBId
.GroupBy(x => x)
.OrderByDescending(x => x.Count())
.First()
.Key;
我发现这有点重,只是得到一个id的最大出现在一个列表....你知道更好的方法吗?
我认为你的代码是足够好的,如果你重写和简化它一点和处理情况,当你的列表是空的。这段代码假设0不是一个有效的Id。
var result = A
.SelectMany(x => x.B)
.Where(x => x.Type == selectedType)
.GroupBy(x => x.Id, new { Id = x.Key, Count = x.Count() })
.OrderByDescending(x => x.Count)
.FirstOrDefault();
Console.WriteLine("Max ID = {0}, Count = {1}", result.Id, result.Count);
如果你仍然认为你现有的代码太复杂,你可以写一个扩展方法来隐藏复杂性
public static int TryGetBIdWithMaxOccur(this IEnumerable<A> input, SelectedTypeEnum selectedType)
{
var result = input
.SelectMany(x => x.B)
.Where(x => x.Type == selectedType)
.GroupBy(x => x.Id, new { Id = x.Key, Count = x.Count() })
.OrderByDescending(x => x.Count)
.Select(x => x.Id)
.FirstOrDefault();
return result;
}
那么你可以这样使用:
var result = A.TryGetBIdWithMaxOccur(SelectedTypeEnum.CoolValue);
if(result != default(int))
{
//do stuff
}
只是一个想法
var bs = A.SelectMany().Where().Select(b=>b.Id).OrderBy();
int current = -1, maxB = -1; // make sure it is stub Id
int currentCount = 0, maxCount = 0;
foreach(var b in bs)
{
if (b != current)
{
// check if previous was max
if (currentCount > maxCount)
{
maxB = current;
maxCount = currentCount;
}
// change current
current = b;
currentCount = 0;
}
currentCount ++;
}
为了使其更短,您可以将Where
选择器放在SelectMany
中,并使用GroupBy
过载:
var idMaxOccur = A
.SelectMany(a => a.B.Where(b => b.Type == selectedType))
.GroupBy(b => b.Id, b => b.Id)
.OrderByDescending(g => g.Count())
.First().Key;