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); 
相關問題