[英]Select List<T> item with max value using LINQ query
我有List loadRecords,其中T類型定義如下
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();
我在這里做錯了什么? 你能解釋一下嗎?
謝謝。
我不這么認為,你需要將它們分組只是為了獲得創紀錄的最高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
,如果collection為空,則不會拋出異常。
您需要對源列表進行排序(降序)並采用第一個元素:
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包已經包含了這樣的MaxBy
方法。
以下應該工作:
var mxKVALoad = loadRecords
.Where(l => l.totalLoadKva == loadRecords.Max(l => l.TotalLoadKva));
另外,您也可以使用MaxBy
從MoreLINQ
庫
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.