我目前正在開發.NET Core 3.1應用程式。
我需要使用 LINQ 過濾串列并盡可能優化性能。
我當前的代碼作業正常,但我想知道性能。
目標:
- SearchResult的結果需要過濾
- 必須只有一個不同的 ID
- 有時我會得到兩個 Id 相同的專案,即 1,然后我需要洗掉一個專案
- 但是:如果有幾個專案具有相同的 Id 值,即 1,那么我需要洗掉沒有 ContactId 的專案。如果兩個專案都沒有 ContactId,我可以選擇第一次出現。
- 最終結果需要按 Id 然后按 ContactId 排序
public class SearchResult
{
public int? Id {get; set;}
public int? ContactId {get; set;}
}
public class Program
{
public static void Main()
{
var searchResults = new List<SearchResult>
{
new SearchResult { Id = 1 },
new SearchResult { Id = 2 }, // yes
new SearchResult { Id = 3 }, // yes
new SearchResult { Id = 4 }, // yes
new SearchResult { Id = 5 },
new SearchResult { Id = 1, ContactId = 1 }, // yes
new SearchResult { Id = 5, ContactId = 3 }, // yes
new SearchResult { Id = 1, ContactId = 1 },
new SearchResult { Id = 8, ContactId = 4 }, // yes
new SearchResult { Id = 1 },
new SearchResult { Id = 2 },
new SearchResult { Id = 10 }, // yes
new SearchResult { Id = 11 }, // yes
new SearchResult { Id = 12 }, // yes
};
// group1 without contactId
var group1 = searchResults
.Where(sr => sr.ContactId == null)
.GroupBy(sr => sr.Id)
.Select(grp => grp.First());
// group2 WITH contactId
var group2 = searchResults
.Where(sr => sr.ContactId != null)
.GroupBy(sr => sr.Id)
.Select(grp => grp.First());
// joined = group1.Id - group2.Id
var joined = group1.Where(g1 => !group2.Any(g2 => g2.Id == g1.Id));
// result = group2 joined
var merged = new List<SearchResult>();
merged.AddRange(group2);
merged.AddRange(joined);
// result ordered by id then by contactId
var result = merged
.OrderBy(x => x.Id)
.ThenBy(x => x.ContactId);
foreach(var sr in result){
Console.WriteLine(sr.Id " " sr.ContactId);
}
}
}
到目前為止一切順利 - 我的代碼“有效”,但也許有人對如何改進此代碼及其性能有所了解?
uj5u.com熱心網友回復:
一個更簡單的解決方案是先對資料進行排序,然后根據 id 對其進行分組。這應該比加入資料更高效。
var searchResults = new List<SearchResult>
{
new SearchResult { Id = 1 },
new SearchResult { Id = 2 }, // yes
new SearchResult { Id = 3 }, // yes
new SearchResult { Id = 4 }, // yes
new SearchResult { Id = 5 },
new SearchResult { Id = 1, ContactId = 1 }, // yes
new SearchResult { Id = 5, ContactId = 3 }, // yes
new SearchResult { Id = 1, ContactId = 1 },
new SearchResult { Id = 8, ContactId = 4 }, // yes
new SearchResult { Id = 1 },
new SearchResult { Id = 2 },
new SearchResult { Id = 10 }, // yes
new SearchResult { Id = 11 }, // yes
new SearchResult { Id = 12 }, // yes
};
var result = searchResults
.OrderBy(x => x.Id)
.ThenByDescending(x => x.ContactId)
.GroupBy(p => p.Id)
.Select(x => x.First());
foreach(var sr in result){
Console.WriteLine(sr.Id " " sr.ContactId);
}
uj5u.com熱心網友回復:
您所需要的只是這個簡單而有效的查詢:
List<SearchResult> resultList = searchResults
.GroupBy(s => s.Id)
.OrderBy(sg => sg.Key)
.Select(sg => sg.OrderBy(s => s.ContactId != null ? 0 : 1).ThenBy(s => s.ContactId).First())
.ToList();
在 之后GroupBy排序,因此減少了排序的必要性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/324906.html
下一篇:如何使用linq更新多行資料?
