按倍数和顺序分组的LINQ查询
本文关键字:LINQ 查询 顺序 | 更新日期: 2023-09-27 18:24:08
我有以下数据结构:
public class Difference
{
public Difference() { }
public Differential Type { get; set; }
public int Magnitude { get; set; }
}
public enum Differential
{
low,
middle,
high
}
我可能有以下数据:
Magnitude Type
4456 low
4456 low
4423 low
4421 low
1000 high
1000 high
1001 high
1560 middle
4456 low
4421 low
我试图返回一个数据集,该数据集为我提供数量相同的魔术及其类型的计数,但每个类型中只有顶部(按计数降序),因此对于上述(按顺序)
值:4456类型:低计数:3
值:1000类型:高计数:2
值:1560类型:中间计数:1
注意到计数为2的4421是如何不在其中的,因为4456的计数更大?
我想我已经接近了,但还没有完全到达:
var query = (from value in differences
group value by new {value.Magnitude, value.Type} into groupjoin
select new
{
Value = groupjoin.Key.Magnitude,
Type = groupjoin.Key.Type,
Count = groupjoin.Count()
})
.OrderByDescending(v => v.Count)
.ThenByDescending(v => v.Value).ThenByDescending(v => v.Type).ToList();
更新
根据Douglas的以下建议,我设法用以下内容来实现它。虽然我不太担心是否存在联系,但如果可能的话,我只想返回First()一个(对于每种类型)。我只能通过循环来完成:
var query = (from value in differences
/*where value.type == Differential.low*/
group value by new {value.Magnitude, value.Type} into groupjoin
select new
{
Value = groupjoin.Key.Magnitude,
Type = groupjoin.Key.Type,
Count = groupjoin.Count()
});
var query2 = query.Where(g1 => !query.Any(g2 =>
g2.Type == g1.Type &&
g2.Count > g1.Count));
int highest = 0;
int lowest = 0;
int middle = 0;
foreach (var item in query2)
{
if (item.Type == Differential.high && item.Count > highest)
{
oresult.numberOfHighHits = item.Count;
oresult.highTimeMagnitude = item.Value;
}
if (item.Type == Differential.low && item.Count > lowest)
{
oresult.numberOfLowHits = item.Count;
oresult.lowTimeMagnitude = item.Value;
}
if (item.Type == Differential.middle && item.Count > middle)
{
oresult.numberOfMiddleHits = item.Count;
oresult.middleTimeMagnitude = item.Value;
}
}
我保留了LINQ查询的第一部分,它给出了不同大小-类型对(及其计数)的分组:
var query =
from value in differences
group value by new {value.Magnitude, value.Type} into groupjoin
select new
{
Value = groupjoin.Key.Magnitude,
Type = groupjoin.Key.Type,
Count = groupjoin.Count()
};
然后,我正在编写另一个LINQ,它接受第一个查询产生的所有分组,并且对于每个分组g1
,检查是否存在任何其他具有相同类型和更大计数的分组g2
。这将确保只返回其类型中计数最大的分组。在平局的情况下(同一类型的多个分组具有相同的最大计数),将返回所有顶部分组。
var query2 = query.Where(g1 =>
!query.Any(g2 =>
g2.Type == g1.Type &&
g2.Count > g1.Count));
编辑:即使在平局的情况下,也要为每种类型返回一个结果,我们可以向query2
过滤器添加另一个条件,这样,如果两个分组具有相同的Type
和相同的Count
,则会选择具有较大Value
的分组(最初命名为Magnitude
)。如果您希望选择Value
较小的一个,只需将最后一个>
替换为<
即可。
这种方法将使查询的结果具有确定性(而不是任意依赖于,例如,原始列表中最先出现的分组)。
var query2 = query.Where(g1 =>
!query.Any(g2 =>
g2.Type == g1.Type &&
(g2.Count > g1.Count || (g2.Count == g1.Count && g2.Value > g1.Value))));