2012-08-04 73 views
19

我有一个list<message>包含类型GuidDateTime(以及其他属性)的属性。我想摆脱该列表中GuidDateTime相同(除一个之外)的所有项目。会有时候,这两个属性是相同的列表中的其他项目,但其他性能会有所不同,所以我不能只用.Distinct()选择不同的列表中的两个属性

List<Message> messages = GetList(); 
//The list now contains many objects, it is ordered by the DateTime property 

messages = from p in messages.Distinct( what goes here?); 

这就是我现在所拥有的,但是看起来,就必须有一个更好的办法

List<Message> messages = GetList(); 

for(int i = 0; i < messages.Count() - 1) //use Messages.Count() -1 because the last one has nothing after it to compare to 
{ 
    if(messages[i].id == messages[i+1}.id && messages[i].date == message[i+1].date) 
    { 
     messages.RemoveAt(i+1); 
    { 
    else 
    { 
     i++ 
    } 
} 
+1

http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property – Shyju 2012-08-04 18:39:38

+0

感谢。我不知道为什么当我搜索时我找不到。 – user1304444 2012-08-04 19:34:29

+0

我很高兴乔恩的答案适合你。请注意:您的“当前使用的方法”不会编译,并且(修复编译错误之后)它不能在所有情况下工作 - 取决于元素的顺序,您会得到不同的**(错误)**结果(毕竟,你只是将相邻元素相互比较)。 – Adam 2012-08-04 19:59:39

回答

52

LINQ到对象不以内置方式轻松提供这一功能,但MoreLINQ有一个方便的方法DistinctBy

messages = messages.DistinctBy(m => new { m.id, m.date }).ToList(); 
+0

我假设MoreLINQ可以免费使用?我没有看到明确写在页面上的任何地方。 – user1304444 2012-08-04 19:32:24

+2

@ user1304444:这是一个开源库 - 请参阅页面左侧的“Apache许可证2.0”链接。 – 2012-08-04 19:33:03

+3

对于其他人查看这个问题,上面提到的链接Shyju似乎也是一个很好的答案。 http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property – user1304444 2012-08-04 19:43:41

2

这是怎么回事?

var messages = messages 
       .GroupBy(m => m.id) 
       .GroupBy(m => m.date) 
       .Select(m => m.First()); 
+0

不能编译...请记住,GroupBy返回一个'IGrouping'。 – Adam 2012-08-04 18:51:42

+0

如果HashSet 在像silverslight这样的开发板上不可用,则此方法有效.... – Thomas 2016-04-05 22:29:56

11

乔恩斯基特的DistinctBy肯定是要走的路,但是如果你有兴趣在定义自己的扩展方法,你可能需要看中这个更简洁的版本:

public static IEnumerable<TSource> DistinctBy<TSource, TKey> 
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) 
{ 
    var known = new HashSet<TKey>(); 
    return source.Where(element => known.Add(keySelector(element))); 
} 

具有相同签名:

messages = messages.DistinctBy(x => new { x.id, x.date }).ToList(); 
+2

我知道这是旧的,但请注意,你必须在调用'DistinctBy()'后调用'ToList()'或'ToArray()'。如果直接在IEnumerable上工作并枚举多次,它将不起作用,因为这些项目在第一次通过IEnumerable的同时添加到HashSet中,并且不会第二次返回,如[.NET Fiddle](https://dotnetfiddle.net/5PUJxl)所示。 – fknx 2017-07-18 10:00:40

1

你可以看看我的PowerfulExtensions图书馆。目前它处于一个非常年轻的阶段,但已经可以使用像Distinct,Union,Intersect等方法,除了任何数量的属性外;

这是你如何使用它:

using PowerfulExtensions.Linq; 
... 
var distinct = myArray.Distinct(x => x.A, x => x.B); 
相关问题