大家好,我有2个例子,我将它命名为A和B
A是一个列表,每个A元素都有一个B元素列表。 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 :(得分:1)
我认为如果你重写并简化它并且在列表为空时处理大小写,你的代码就足够了。此代码假定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
}
答案 1 :(得分:0)
为了缩短它,您可以将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;
答案 2 :(得分:0)
只是一个想法
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 ++;
}