C# 选择组属性最大值的结果
这是我的密码:C# 选择组属性最大值的结果,c#,linq,C#,Linq,这是我的密码: class Data { public DateTime Date { get; private set; } public int Income { get; private set; } public Data(DateTime date, int income) { Date = date; Income = income; } } public static List<Data> Get
class Data
{
public DateTime Date { get; private set; }
public int Income { get; private set; }
public Data(DateTime date, int income)
{
Date = date;
Income = income;
}
}
public static List<Data> GetSampleData()
{
var now = DateTime.Now.Date;
return new List<Data>()
{
new Data(now.AddMinutes(-15), 15), //23:45
new Data(now.AddMinutes(-30), 10), //23:30
new Data(now.AddMinutes(-45), 7), //23:15
new Data(now.AddMinutes(-55), 8), //23:05
new Data(now.AddMinutes(-62), 0), //23:58
new Data(now.AddMinutes(-67), 12), //22:53
new Data(now.AddMinutes(-70), 1), //22:50
};
}
我管理的是:
var data = GetSampleData();
var result = data.GroupBy(x => new
{
hour = x.Date.Hour
})
.Select(z => new
{
Sum = z.Sum(a => a.Income),
Hour = z.Key.hour
})
.OrderByDescending(x => x.Sum)
.FirstOrDefault();
这是有效的。但是我不喜欢我的解决方案,因为OrderByDescending
。有没有更好的办法解决这个问题?如果可能的话,我想使用Max
解决方案,但我无法编码它。它将是:
从组中获取最大收入总和
您可以使用聚合:
.Aggregate( (curMax, x) => (curMax == null) || (x.Sum > curMax.Sum) ? x : curMax );
在我看来,你所做的一切都很好,因为你可以有超过一个小时的时间和相同的最高收入。也就是说,您可以始终使用
Aggregate
:
var sums = data.GroupBy(d => d.Date.Hour)
.Select(g => new { hour = g.Key, sum = g.Sum(d => d.Income) });
var maxData = sums.Aggregate(
sums.FirstOrDefault(), //First parameter
(max, next) => next.sum > max.sum ? next : max, //Second parameter
sum => sum //Third parameter
);
说明:
Aggregate
函数使用种子作为第一个参数,在本例中,种子是总和的第一项如果检查
maxData
,则可以使用.NET较新版本中具有属性hour
和sum
的聚合类型(总和必须是第一个元组项):
或作为单独的变量:
(int Sum, int Hour) = data.GroupBy(d => d.Date.Hour)
.Max(g => (g.Sum(d => d.Income), g.Key));
在较旧的.NET版本中: 如果有多个元组具有max sum,则结果是具有max hour的元组
没有元组的一个稍微更有效的替代方法是对两个值使用相同的数字:
int maxSumHour = data.GroupBy(d => d.Date.Hour)
.Max(g => g.Sum(d => d.Income) * 100 + g.Key));
int Sum = maxSumHour / 100, Hour = maxSumHour % 100;
如果您真的想要使用Max()的解决方案,只需不要使用匿名类型,而是首先创建一个类/结构并实现IComparable
public struct IncomePerHour : IComparable<IncomePerHour>
{
public int Income { get; set; }
public int Hour { get; set; }
public int CompareTo(IncomePerHour other)
{
return Income.CompareTo(other.Income);
}
}
如果您想重复使用您的数据:
public class Data : IComparable<Data>
{
public DateTime Date { get; private set; }
public int Income { get; private set; }
public Data(DateTime date, int income)
{
Date = date;
Income = income;
}
public int CompareTo(Data other)
{
return Income.CompareTo(other.Income);
}
}
class Program
{
var data = GetSampleData();
var result = data.GroupBy(x => x.Date.Hour)
.Select(z => new Data (z.First().Date, z.Sum(a => a.Income)))
.Max();
Console.WriteLine($"Hour: {result.Date.Hour}, Income:{result.Income}");
}
公共类数据:i可比较
{
公共日期时间日期{get;private set;}
公共整数收入{get;私有集合;}
公共数据(日期时间日期,国际收入)
{
日期=日期;
收入=收入;
}
公共整数比较(数据其他)
{
回报收入。与(其他收入)相比;
}
}
班级计划
{
var data=GetSampleData();
var result=data.GroupBy(x=>x.Date.Hour)
.Select(z=>newdata(z.First().Date,z.Sum(a=>a.Income)))
.Max();
WriteLine($“Hour:{result.Date.Hour},Income:{result.Income}”);
}
您可以在此处使用Aggregate
。考虑接受答案如果它解决了你的问题收入是40:(和)(15,10,7,8,0)我认为这是正确的,因为当比较元组时,它比较每个元素的顺序还是相似的?“克里斯是的,所以总和必须是第一个元组项。如果超过一个小时的最大和,则结果是具有max hourCool的元组。我想这可能是值得的,因为我认为这不是每个人都会完全熟悉的行为。嗨,这有帮助吗?
int maxSumHour = data.GroupBy(d => d.Date.Hour)
.Max(g => g.Sum(d => d.Income) * 100 + g.Key));
int Sum = maxSumHour / 100, Hour = maxSumHour % 100;
public struct IncomePerHour : IComparable<IncomePerHour>
{
public int Income { get; set; }
public int Hour { get; set; }
public int CompareTo(IncomePerHour other)
{
return Income.CompareTo(other.Income);
}
}
var data = GetSampleData();
var result = data.GroupBy(x => x.Date.Hour)
.Select(z => new IncomePerHour
{
Income = z.Sum(a => a.Income),
Hour = z.Key
})
.Max();
public class Data : IComparable<Data>
{
public DateTime Date { get; private set; }
public int Income { get; private set; }
public Data(DateTime date, int income)
{
Date = date;
Income = income;
}
public int CompareTo(Data other)
{
return Income.CompareTo(other.Income);
}
}
class Program
{
var data = GetSampleData();
var result = data.GroupBy(x => x.Date.Hour)
.Select(z => new Data (z.First().Date, z.Sum(a => a.Income)))
.Max();
Console.WriteLine($"Hour: {result.Date.Hour}, Income:{result.Income}");
}