c# - "better"(更简单,更快,无论如何)版本'distinct by delegate'?

标签 c# linq

我讨厌发布此内容,因为它有点主观,但感觉有一种我没有想到的更好的方法来做到这一点。

有时我想通过某些列/属性来“区分”集合,但又不想丢弃其他列(是的,这确实会丢失信息,因为最终得到的其他列的值变得任意)。

请注意,此扩展的功能不如采用 IEqualityComparer<T> 的 Distinct 重载强大。因为这样的东西可以做更复杂的比较逻辑,但这就是我现在所需要的:)

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> getKeyFunc)
{
    return from s in source
            group s by getKeyFunc(s) into sourceGroups
            select sourceGroups.First();
}

使用示例:

var items = new[]
{
    new { A = 1, B = "foo", C = Guid.NewGuid(), },
    new { A = 2, B = "foo", C = Guid.NewGuid(), },
    new { A = 1, B = "bar", C = Guid.NewGuid(), },
    new { A = 2, B = "bar", C = Guid.NewGuid(), },
};

var itemsByA = items.DistinctBy(item => item.A).ToList();
var itemsByB = items.DistinctBy(item => item.B).ToList();

最佳答案

给你。我不认为这比你自己的版本更有效,但它应该有一点优势。它只需要一次通过序列,产生每个项目,而不是需要首先对整个序列进行分组。

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
    this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    return source.DistinctBy(keySelector, null);
}

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (keySelector == null)
        throw new ArgumentNullException("keySelector");

    return source.DistinctByIterator(keySelector, keyComparer);
}

private static IEnumerable<TSource> DistinctByIterator<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer)
{
    var keys = new HashSet<TKey>(keyComparer);

    foreach (TSource item in source)
    {
        if (keys.Add(keySelector(item)))
            yield return item;
    }
}

关于c# - "better"(更简单,更快,无论如何)版本'distinct by delegate'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3259816/

相关文章:

c# - 对使用 LINQ 查询 SQL Server 数据库 : edmx? dbml 感到困惑?数据集?

c# - List<T>.Contains 未显示过载

c# - 通过反射在数组中设置值

c# - LINQ 查询两个并行数组的子集

javascript - Linq JS 将名称首字母分组的对象

c# - LINQ 中的匿名类型

.net - 在 VB.Net 中使用 LINQ 将集合拆分为 n 个部分

c# - HttpRequest.Content.IsMimeMultipartContent() 在应该返回 true 时返回 false

c# - 为什么我无法使用反射获取 LinkBut​​ton 事件的事件处理程序?

c# - 如何在连接时从 WebClient.DownloadDataAsync() 获取更多信息?