当前位置:  开发笔记 > 编程语言 > 正文

为什么没有Linq方法通过谓词返回不同的值?

如何解决《为什么没有Linq方法通过谓词返回不同的值?》经验,为你挑选了2个好方法。

我想在列表中获取不同的值,但不是通过标准的相等比较.

我想做的是这样的:

return myList.Distinct( (x, y) => x.Url == y.Url );

我不能,Linq中没有扩展方法可以做到这一点 - 只需要一个IEqualityComparer.

我可以用这个来解决它:

return myList.GroupBy( x => x.Url ).Select( g => g.First() );

但这似乎很混乱.它也没有做同样的事情 - 我只能在这里使用它因为我有一把钥匙.

我也可以添加自己的:

public static IEnumerable Distinct( 
    this IEnumerable input, Func compare )
{
    //write my own here
}

但这似乎就像写一些应该存在的东西一样.

任何人都知道为什么这种方法不存在?

我错过了什么吗?



1> Jon Skeet..:

当然,这很烦人.它也是我的"MoreLINQ"项目的一部分,我必须在某些方面注意:)有很多其他操作在投影时有意义,但返回原始--MaxBy和MinBy春天的想法.

正如你所说,它很容易编写 - 虽然我更喜欢名称"DistinctBy"来匹配OrderBy等.如果您感兴趣,这是我的实现:

    public static IEnumerable DistinctBy
        (this IEnumerable source,
         Func keySelector)
    {
        return source.DistinctBy(keySelector,
                                 EqualityComparer.Default);
    }

    public static IEnumerable DistinctBy
        (this IEnumerable source,
         Func keySelector,
         IEqualityComparer comparer)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        if (keySelector == null)
        {
            throw new ArgumentNullException("keySelector");
        }
        if (comparer == null)
        {
            throw new ArgumentNullException("comparer");
        }
        return DistinctByImpl(source, keySelector, comparer);
    }

    private static IEnumerable DistinctByImpl
        (IEnumerable source,
         Func keySelector,
         IEqualityComparer comparer)
    {
        HashSet knownKeys = new HashSet(comparer);
        foreach (TSource element in source)
        {
            if (knownKeys.Add(keySelector(element)))
            {
                yield return element;
            }
        }
    }


如果我不得不猜测,我猜想与IQueryable 选项的奇偶校验,以及TSQL中的现实(没有生病).所以DISTINCT(table.column)很好,但你需要一个方便的密钥和一些更复杂的TSQL for DistinctBy ...

2> Amy B..:

但这似乎很混乱.

它并不凌乱,这是正确的.

如果你想要DistinctFirstName的Programmers并且有四个David,你想要哪一个?

如果你是Group程序员通过FirstName并拿First一个,那么很明显你想要做的是四个大卫的情况.

我只能在这里使用它因为我有一把钥匙.

您可以使用相同的模式执行多个"不同"键:

return myList
  .GroupBy( x => new { x.Url, x.Age } )
  .Select( g => g.First() );

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有