這可能是顯而易見的,但我無法繞過它。在LINQ中,如何爲每個ID選擇一個項目?
我有一個項目清單,例如:
BOB 5
Brian 5
Sam 6
James 7
Emily 8
Sandra 8
Michael 8
這些都是在一個List<MyObject>
我想過濾列表所以每個ID只有1項,通過選擇第一個用唯一身份。
我應該結束了
BOB 5
Sam 6
James 7
Emily 8
我無法制定出一個乾淨的方式來做到這一點。有任何想法嗎?
這可能是顯而易見的,但我無法繞過它。在LINQ中,如何爲每個ID選擇一個項目?
我有一個項目清單,例如:
BOB 5
Brian 5
Sam 6
James 7
Emily 8
Sandra 8
Michael 8
這些都是在一個List<MyObject>
我想過濾列表所以每個ID只有1項,通過選擇第一個用唯一身份。
我應該結束了
BOB 5
Sam 6
James 7
Emily 8
我無法制定出一個乾淨的方式來做到這一點。有任何想法嗎?
使用GroupBy
和First
方法組合:
var results = source.GroupBy(x => x.Id).Select(g => g.First()).ToList();
或者作爲基於語法的查詢:
var results = (from i in source
group i by i.Id into g
select g.First()).ToList();
精靈,作品一種享受。謝謝!另一個用於工具集。 – NibblyPig
我認爲,正確的方法是實現IEquatable
然後使用.Distinct()
這裏是如何使用它的鏈接。這樣您可以更好地控制第一個項目的處理方式。
這裏有一個關於如何重寫[IEquatable]的問題(http://stackoverflow.com/questions/3897672/linq-object-equality-and-how-to-properly-override-it?rq=1) – SQLMason
你需要一個更好的直觀方法,可以做「者皆不同」。
public static IEnumerable<TSource> Distinct<TSource,TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var seen = new HashSet<TKey>();
foreach(var x in source)
{
var key = keySelector(x);
if (seen.Add(key);)
yield return x;
}
}
關於無關請注意,請不要[批准建議編輯](http://stackoverflow.com/review/suggested-edits/2763311)使用反引號強調,但拒絕或改進它們 - 請參閱[here](http://meta.gaming.stackexchange.com/q/7437/88)爲什麼 –
當然,這很有道理 –
感謝您的理解:) –
這應該是相當快:
int c = 0;
var results = source.Where(i =>
{
if (i.Id > c)
{
c = i.Id;
return true;
}
else
return false;
}).ToList();
(可以說)以上的GroupBy /第一組合效率,但它需要ID(-1)的特殊空值,以及與同所有項目ID列表中的分組:
int currentID = -1;
var unique = list.Where(x =>
{
if (currentID != -1 && currentID == x.ID)
return false;
currentID = x.ID;
return true;
});
可能與。首先(組合GROUPBY)應該工作,但我無法制定它:( –
你怎麼知道挑鮑勃布萊恩,而不是我的意思嗎? ,你說「冷杉噸「,但有什麼資格作爲第一?日期時間戳,字母順序... – SQLMason
你見過這個:http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property? –