[英]How do I get a distinct list of list types
This is my code (copy and paste it into linqpad if you like) 这是我的代码(如果你愿意,可以将它复制并粘贴到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();
The results I get back are {7,8}, {7,8}, {7,8,9} 我得到的结果是{7,8},{7,8},{7,8,9}
What I want is {7,8}, {7,8,9}. 我想要的是{7,8},{7,8,9}。
Basically I want to remove the duplicate lists. 基本上我想删除重复列表。 I haven't tried this but I think I could probably achieve by creating a comparer and passing it into the Distinct method.
我没有尝试过这个,但我想我可以通过创建一个比较器并将其传递给Distinct方法来实现。 However I would like to eventually use this in a Linq to Entities query without bringing thousands of rows back to the client so that isn't a good option.
但是我想最终在Linq to Entities查询中使用它,而不会将数千行返回给客户端,因此这不是一个好的选择。
For extra clarification...I need to return a List> where the contents of each inner list is distinct in comparison to any of the other inner list. 为了进一步说明......我需要返回一个List>,其中每个内部列表的内容与任何其他内部列表相比是不同的。
The problem is that .Distinct()
determines what's distinct based on the GetHashCode()
and Equals()
implementation of the underlying objects. 问题是
.Distinct()
根据底层对象的GetHashCode()
和Equals()
实现来确定什么是不同的。 In this case, the underlying object is something that implements IEnumerable<>
, but which uses the default object
implementation for those methods--which is based purely on whether the objects occupy the same space in memory. 在这种情况下,底层对象是实现
IEnumerable<>
东西,但它使用这些方法的默认object
实现 - 这完全基于对象是否占用内存中的相同空间。 So as far as it can tell, the sequences are not distinct, even though they have the same values in them. 因此,就它所知,序列并不是截然不同的,即使它们具有相同的值。
How about this? 这个怎么样?
messageUsers
.GroupBy (x => x.MsgId, x => x.UserId)
.GroupBy(x => string.Join(",", x))
.Select(x => x.FirstOrDefault())
.Dump();
The idea is to group by a key that represents the combined value of the elements in your list. 我们的想法是按一个键进行分组,该键表示列表中元素的组合值。 You could also pass a custom
IEqualityComparer<>
to the Distinct
method in your original code, but that seems like a fair bit of effort for something so trivial. 您还可以将自定义
IEqualityComparer<>
传递给原始代码中的Distinct
方法,但这对于一些如此微不足道的事情来说似乎是相当费力的。
It's worth noting that this won't work very well if you're using LINQ to Entities or something like that. 值得注意的是,如果您使用LINQ to Entities或类似的东西,这将无法正常工作。
To make it a List<List<int>>
, you'll need a few .ToList()
s thrown in there: 要使它成为
List<List<int>>
,你需要在其中抛出几个.ToList()
:
messageUsers
.GroupBy (x => x.MsgId, x => x.UserId)
.GroupBy(x => string.Join(",", x))
.Select(x => x.FirstOrDefault().ToList())
.ToList()
.Dump();
But I'm frankly not sure why that matters to you. 但我坦率地不确定为什么这对你很重要。
Here is an alternative answer: 这是一个替代答案:
messageUsers
.GroupBy (x => x.MsgId, y=>y.UserId)
.Select (x => new HashSet<int>(x))
.Distinct(HashSet<int>.CreateSetComparer())
.Dump();
Consider the following input: 考虑以下输入:
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 }};
What result do you want? 你想要什么结果?
{7,8}, {7,8,9} or {7,8}, {8,7}, {7,8,9}. {7,8},{7,8,9}或{7,8},{8,7},{7,8,9}。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.