简体   繁体   English

如何获得不同的列表类型列表

[英]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或类似的东西,这将无法正常工作。

Update 更新

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM