【问题标题】:LINQ MoreThan(predicate, limit) extension instead of Count(predicate) > limit?LINQ MoreThan(predicate, limit) 扩展而不是 Count(predicate) > limit?
【发布时间】:2011-07-26 10:09:46
【问题描述】:

检查 IEnumerable 集合是否包含多于或少于 X 个满足谓词的元素的最佳方法是什么?

我目前正在使用.Count(lambda) <= limit,但这会使程序不必要地遍历整个集合。

【问题讨论】:

    标签: c# .net linq comparison operator-keyword


    【解决方案1】:

    您可以使用此表达式:.Skip(limit).Any() 等效于 Count() > limit。但如果你的列表是ICollectionCount() 更可取。

    谓词版本:

    public static bool MoreThan<TSource>(this IEnumerable<TSource> source, 
        Func<TSource, bool> predicate, int limit)
    {
        int i = 0;
    
        foreach (var item in source)
        {
            if (predicate(item))
            {
                i++;
    
                if (i > limit)
                {
                    return true;
                }
            }
    
        }
    
        return false;
    }
    

    【讨论】:

    • 这如何回答这个问题?它不计算与问题要求的谓词匹配的元素。
    • @Kirill,一旦条件不再满足,SkipWhile(predicate) 将返回所有元素。
    • @Erwin,真的。我从我的答案中删除了这个。
    • @Erwin,如果您使用.Count(predicate),我认为这是最合适的解决方案。
    【解决方案2】:

    你可以定义一些扩展方法:

    static bool LessThan<T>(this IEnumerable<T> enumerable, int count, Func<T, bool> predicate)
    {
        int found = 0;
        foreach (var item in enumerable)
        {
            if (predicate(item))
            {
                found++;
                if (found >= count)
                    return false;
            }
        }
        return true;
    }
    
    static bool MoreThan<T>(this IEnumerable<T> enumerable, int count, Func<T, bool> predicate)
    {
        int found = 0;
        foreach (var item in enumerable)
        {
            if (predicate(item))
            {
                found++;
                if (found > count)
                    return true;
            }
        }
        return false;
    }
    

    然后像这样使用它们:

    var col = new[] { 1, 6, 4, 8, 3, 5, 1, 7 };
    var res1 = col.MoreThan(2, c => c == 1); //false
    var res2 = col.MoreThan(1, c => c == 1); //true
    var res3 = col.LessThan(4, c => c > 5); //true
    var res4 = col.LessThan(3, c => c > 5); //false
    

    【讨论】:

    • 非常好,虽然它可能应该是 (found > count) 在第一个和 (found >= count) 在第二个。
    • 当匹配元素的数量等于您正在搜索的数量时,这将使它们返回 true,这对于名称“LessThan”和“MoreThan”没有意义。跨度>
    猜你喜欢
    • 2016-04-17
    • 2012-01-29
    • 1970-01-01
    • 2020-01-02
    • 2011-02-08
    • 2013-06-05
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    相关资源
    最近更新 更多