c# - 当集合有多个项目时,相当于 Linq 的 Any() 函数

标签 c# .net linq .net-core

在 C# 中,使用 Linq,如果我想检查集合是否有任何元素,我可以这样做:

someCollection.Any()

哪个更好

someCollection.Count() > 0

由于后者会计算集合中的所有项目,因此当我并不真正关心有多少项目时,我只想知道是否有。

是否有等效的方法可以检查集合是否包含多个项目?像这样的东西:

someCollection.Many()

而不是必须做

someCollection.Count() > 1

我知道这是一个愚蠢的问题,而且根据我的研究,它看起来并不存在。但由于它是我经常使用的东西,我想我应该向社区仔细检查一下。

谢谢

最佳答案

根据我的评论:

首先,您应该检查是否 IEnumerable<T> source 实际上是 IReadOnlyCollection<T>ICollection<T>因为那有一个 .Count您可以使用的属性 - 这比任何迭代都更好。

假设您的IEnumerable<T>没有O(1) .Count属性,如果您想查看是否有至少 1 个元素(即“至少 2 个或更多”),则使用 source.Take(2).Count() == 2source.Skip(1).Any() .

像这样:

public static Boolean Many<T>( this IEnumerable<T> source )
{
    if( source is null ) throw new ArgumentNullException(nameof(source));

    if( source is ICollection<T> col ) return col.Count >= 2;
    else if( source is IReadOnlyCollection<T> roCol ) return roCol.Count >= 2;

    return source.Take(2).Count() == 2;
}

如果您想提高效率,请进行手动迭代:

public static Boolean Many<T>( this IEnumerable<T> source )
{
    if( source is null ) throw new ArgumentNullException(nameof(source));

    if( source is ICollection<T> col ) return col.Count >= 2;
    else if( source is IReadOnlyCollection<T> roCol ) return roCol.Count >= 2;

    Int32 count = 0;
    using( IEnumerator<T> iter = source.GetEnumerator() )
    {
        while( iter.MoveNext() && count < 2 )
        {
            count += 1;
        }
    }

    return count == 2;
}

如果您想提高效率,请允许消费者提供非盒装枚举器(例如 List<T>.Enumerator ):

public static Boolean Many<TEnumerable,TEnumerator,TElement>( /*this*/ TEnumerable source, Func<TEnumerable,TEnumerator> getEnumerator )
    where TEnumerable : IEnumerable<TElement>
    where TEnumerator : IEnumerator<TElement>
{
    if( source        is null ) throw new ArgumentNullException(nameof(source));
    if( getEnumerator is null ) throw new ArgumentNullException(nameof(getEnumerator));
    
    //

    if     ( source is ICollection<TElement>           col ) return col  .Count >= 2;
    else if( source is IReadOnlyCollection<TElement> roCol ) return roCol.Count >= 2;

    Int32 count = 0;
    using( TEnumerator iter = getEnumerator( source ) )
    {
        while( iter.MoveNext() && count < 2 )
        {
            count += 1;
        }
    }

    return count == 2;
}

像这样使用:

List<String> listOfStrings = new List<String>() { ... };

if( listOfStrings.Many</*TEnumerable:*/ List<String>, /*TEnumerator:*/ List<String>.Enumerator, /*TElement:*/ String >( l => l.GetEnumerator() ) )
{
    
}

关于c# - 当集合有多个项目时,相当于 Linq 的 Any() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73443067/

相关文章:

c# - 这个条件在sql里怎么写?

c# - Linq 到实体 SqlFunctions.DatePart

C# BackgroundWorker 不工作

.net - IIS 6 使用通配符应用程序映射时压缩静态文件

linq - 有没有办法将 PredicateBuilder 与 Azure 表存储结合使用?

c# - 如何将此 linqTOsql 查询转换为 lambda

c# - 运行大型 SQL 语句并填充 gridview

c# - 与 WCF 服务共享领域模型

linq - 使用 Linq 连接动态数据表

C#:如何只返回字符串中的第一组大写字母单词?