在LINQ中,如何为每个ID选择一个项目?

时间:2013-08-16 12:05:00

标签: c# linq

这可能是显而易见的,但我无法理解它。

我有一个项目列表,例如:

BOB 5
Brian 5
Sam 6
James 7
Emily 8
Sandra 8
Michael 8

这些是List<MyObject>

我想过滤列表,因此每个ID只有1个项目,选择第一个具有唯一ID的项目。

我最终应该

BOB 5
Sam 6
James 7
Emily 8

我在制定干净的方法时遇到了麻烦。有什么想法吗?

5 个答案:

答案 0 :(得分:7)

使用GroupByFirst方法组合:

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();

答案 1 :(得分:1)

我认为正确的方法是实施IEquatable

然后使用.Distinct()

以下是如何使用它的链接。这样您就可以更好地控制第一个项目的处理方式。

http://msdn.microsoft.com/en-us/library/bb348436.aspx

答案 2 :(得分:0)

您需要一种更好的Distinct方法,可以“按键分开”。

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;
    }
}

答案 3 :(得分:0)

这应该非常快:

int c = 0;
var results = source.Where(i =>
{
    if (i.Id > c)
    {
        c = i.Id;
        return true;
    }
    else
        return false;
}).ToList();

答案 4 :(得分:0)

(可以说)比G​​roupBy / First组合更有效,但它需要ID(-1)的特殊空值,并且所有具有相同ID的项目都要在列表中分组:

        int currentID = -1;
        var unique = list.Where(x =>
        {
            if (currentID != -1 && currentID == x.ID)
                return false;

            currentID = x.ID;
            return true;
        });