LINQ +查找非空值的计数

时间:2010-04-02 07:03:52

标签: vb.net linq-to-sql

我有一张下面结构的表格。

ID VALUE
1 3.2
2 NULL
4 NULL
5 NULL
7 NULL
10 1.8
11 NULL
12 3.2
15 4.7
17 NULL
22 NULL
24 NULL
25 NULL
27 NULL
28 7

我想得到表中连续空值的最大数量。

非常感谢任何帮助。

感谢 Ashutosh说

3 个答案:

答案 0 :(得分:0)

表格是否真的以有意义的方式排序?

我认为要巧妙地做到这一点,你需要一个与GroupBy不同的分组运算符,例如GroupConsecutive,所以如果它们具有相同的密钥,则所有单独的组保持分离而不是组合。

不幸的是,我的VB是生锈的,不存在的,但你可以在精神上转换它:

public static class X
{
    private class Grouping<K, V> : List<V>
    {
        public K Key { get; set; }
    }

    public static IEnumerable<IGrouping<TKey, TValue>> GroupConsecutive(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector)
    {
        Grouping current = null;

        foreach (var elem in source)
        {
            var key = keySelector(elem);
            if (current == null || !current.Key.Equals(key))
            {
                if (current != null)
                    yield return current;
                current = new Grouping { Key = key };
            }

            current.Add(elem);
        }

        if (current != null)
            yield return current;

    }
}

现在你可以说:

table.GroupConsecutive(r => r.Value).Where(g => g.Key == null).Max(g => g.Count);

此表被视为IEnumerable,因此这一切都发生在内存中。

如果是这样,你可能最好在原始SQL中执行它。

答案 1 :(得分:0)

你总是可以通过艰难的方式完成这项工作,并在返回后简单地循环遍历集合。

简单算法

for each item in collection
   if element null
      increment counter
   if element not null
      compare counter to existing max, update as necessary
      reset counter

display or otherwise use max

我喜欢LINQ,但我不确定它是如何在这里使用的。就像我说的那样,总会有人通过抛出单线方法来接近并关闭我。

答案 2 :(得分:0)

怎么样(C#我害怕):

var count = data.Aggregate(new { tmp = 0, max = 0 }, (current, item) => 
     item.Value == null ? new { tmp = current.tmp + 1, 
                                max = Math.Max(current.tmp + 1, current.max) }
                        : new { tmp = 0, current.max }).max;

换句话说,我们始终保持当前计数和最大值。请注意,这太可怕了。它似乎与你给出的样本数据一起工作......

我不确定这是否适用于LINQ to SQL,请注意。请注意,在有意义之前,您需要指定一个排序 - 数据库表是“集合”,没有连续值的概念。