[英]How do I get a distinct list of list types
這是我的代碼(如果你願意,可以將它復制並粘貼到linqpad中)
var messageUsers = new [] {
new { MsgId = 2, UserId = 7 },
new { MsgId = 2, UserId = 8 },
new { MsgId = 3, UserId = 7 },
new { MsgId = 3, UserId = 8 },
new { MsgId = 1, UserId = 7 },
new { MsgId = 1, UserId = 8 },
new { MsgId = 1, UserId = 9 }};
messageUsers
.GroupBy (x => x.MsgId, x => x.UserId)
.Select (x => x.Select (y => y))
.Distinct()
.Dump();
我得到的結果是{7,8},{7,8},{7,8,9}
我想要的是{7,8},{7,8,9}。
基本上我想刪除重復列表。 我沒有嘗試過這個,但我想我可以通過創建一個比較器並將其傳遞給Distinct方法來實現。 但是我想最終在Linq to Entities查詢中使用它,而不會將數千行返回給客戶端,因此這不是一個好的選擇。
為了進一步說明......我需要返回一個List>,其中每個內部列表的內容與任何其他內部列表相比是不同的。
問題是.Distinct()
根據底層對象的GetHashCode()
和Equals()
實現來確定什么是不同的。 在這種情況下,底層對象是實現IEnumerable<>
東西,但它使用這些方法的默認object
實現 - 這完全基於對象是否占用內存中的相同空間。 因此,就它所知,序列並不是截然不同的,即使它們具有相同的值。
這個怎么樣?
messageUsers
.GroupBy (x => x.MsgId, x => x.UserId)
.GroupBy(x => string.Join(",", x))
.Select(x => x.FirstOrDefault())
.Dump();
我們的想法是按一個鍵進行分組,該鍵表示列表中元素的組合值。 您還可以將自定義IEqualityComparer<>
傳遞給原始代碼中的Distinct
方法,但這對於一些如此微不足道的事情來說似乎是相當費力的。
值得注意的是,如果您使用LINQ to Entities或類似的東西,這將無法正常工作。
要使它成為List<List<int>>
,你需要在其中拋出幾個.ToList()
:
messageUsers
.GroupBy (x => x.MsgId, x => x.UserId)
.GroupBy(x => string.Join(",", x))
.Select(x => x.FirstOrDefault().ToList())
.ToList()
.Dump();
但我坦率地不確定為什么這對你很重要。
這是一個替代答案:
messageUsers
.GroupBy (x => x.MsgId, y=>y.UserId)
.Select (x => new HashSet<int>(x))
.Distinct(HashSet<int>.CreateSetComparer())
.Dump();
考慮以下輸入:
var messageUsers = new [] {
new { MsgId = 2, UserId = 7 },
new { MsgId = 2, UserId = 8 },
new { MsgId = 3, UserId = 8 },
new { MsgId = 3, UserId = 7 },
new { MsgId = 1, UserId = 7 },
new { MsgId = 1, UserId = 8 },
new { MsgId = 1, UserId = 9 }};
你想要什么結果?
{7,8},{7,8,9}或{7,8},{8,7},{7,8,9}。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.