我有List loadRecords,其中T type定义如下
public class TransformerLoadRecord
{
public double TotalLoadKva { get; set; }
public double TotalLoadKwh { get; set; }
public string LoadDate { get; set; }
public string LoadTime { get; set; }
public long Fid { get; set;}
public string UserId { get; set; }
public string SessionId { get; set; }
public override string ToString()
{
return "User Id:" + UserId +
" Session Id:" + SessionId +
" Fid:" + Fid.ToString() +
" Load Date:" + LoadDate +
" Load Time:" + LoadTime +
" Total Load KWH:" + TotalLoadKwh.ToString() +
" Total Load KVA:" + TotalLoadKva.ToString();
}
}
我需要从项目列表中获取最大TotalLoadKva项目(约1900) 这是工作
var mxKVALoad = loadRecords.Max(l => l.TotalLoadKva);
但是我需要所有其他属性,并且此代码不起作用并返回多个项目
var maxLoadRecord = from txLoadValues in loadRecords
group txLoadValues by txLoadValues.TotalLoadKva
into txLoadValueGroup
select txLoadValueGroup.OrderByDescending(l => l.TotalLoadKva).FirstOrDefault();
我在这里做错了什么?你能解释一下吗?
谢谢。
答案 0 :(得分:2)
我不这么认为你需要将它们分组才能获得最高TotalLoadKva
的记录,你可以使用OrderByDescending
对TotalLoadKva
进行排序,然后选择顶部使用First
或FirstOrDefault
方法的第一条记录:
var maxKVALoad = loadRecords.OrderByDescending(l => l.TotalLoadKva).FirstOrDefault();
// will return the record with highest value of TotalLoadKva
首选方式是使用FirstOrDefault()
,因为First()
会抛出异常说:
序列不包含元素
如果保证总会返回行,那么First()
可以安全使用,否则使用FirstOrDefault
如果集合为空则不会抛出异常。
答案 1 :(得分:2)
您需要对源列表进行排序(降序)并获取第一个元素:
var elementWithMaxKVA = loadRecords.OrderByDescending(l => l.TotalLoadKva).FirstOrDefault();
但这不是最快的方法,因为OrderBy*
除了查找最大值之外还需要做更多工作。
您可以改为实现自己的扩展方法:
// error handling and argument checks ommitted for brevity
public static TSource MaxBy<TSource, TComp>(this IEnumerable<TSource> source, Func<TSource, TComp> selector) where TComp : IComparable
{
using (var enumerator = source.GetEnumerator())
{
TSource max = default(TSource);
TComp maxV = default(TComp);
if (!enumerator.MoveNext()) return max; // or throw
max = enumerator.Current;
maxV = selector(max);
while(enumerator.MoveNext())
{
TSource current = enumerator.Current;
TComp currentV = selector(current);
if (currentV.CompareTo(maxV) <= 0) continue;
maxV = currentV;
max = current;
}
return max;
}
}
并像
一样使用它var elementWithMaxKVA = loadRecords.MaxBy(l => l.TotalLoadKva);
我认为MoreLinq nuget package已经包含了这样的MaxBy
方法。
答案 2 :(得分:0)
以下内容应该有效:
var mxKVALoad = loadRecords
.Where(l => l.totalLoadKva == loadRecords.Max(l => l.TotalLoadKva));
或者,您可以使用MoreLINQ
library
MaxBy