这可能很明显,但我很难理解它。
我有一个项目清单,例如:
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
我很难找到一种干净的方法来做到这一点。有任何想法吗?
用途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();
我相信正确的方法是实施IEquatable
然后使用.Distinct()
这是如何使用它的链接。这样,您可以更好地控制第一项的处理方式。
您需要一种更好的 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;
}
}
这应该很快:
int c = 0;
var results = source.Where(i =>
{
if (i.Id > c)
{
c = i.Id;
return true;
}
else
return false;
}).ToList();
(可以说)比 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;
});