3

这可能很明显,但我很难理解它。

我有一个项目清单,例如:

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

这些在一个List<MyObject>

我想通过选择具有唯一 ID 的第一个项目来过滤列表,以便每个 ID 只有 1 个项目。

我应该结束

BOB 5
Sam 6
James 7
Emily 8

我很难找到一种干净的方法来做到这一点。有任何想法吗?

4

5 回答 5

8

用途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();
于 2013-08-16T12:08:03.620 回答
1

我相信正确的方法是实施IEquatable

然后使用.Distinct()

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

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

于 2013-08-16T12:09:32.350 回答
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;
    }
}
于 2013-08-16T12:18:14.740 回答
0

这应该很快:

int c = 0;
var results = source.Where(i =>
{
    if (i.Id > c)
    {
        c = i.Id;
        return true;
    }
    else
        return false;
}).ToList();
于 2013-08-16T12:23:16.350 回答
0

(可以说)比 GroupBy/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;
        });
于 2013-08-16T12:24:49.870 回答