【问题标题】:Using Linq to check if a list includes null values in the middle使用 Linq 检查列表是否在中间包含空值
【发布时间】:2012-07-24 05:53:42
【问题描述】:

我有一个要求,我需要从列表中过滤掉空值,只有当空值出现在第一个非空值之后和最后一个非空值之前。

Product one = new Product { Name="A" Priority="1" Value=null };
Product two = new Product { Name="A" Priority="2" Value=null };
Product three = new Product { Name="A" Priority="3" Value="10" };
Product four = new Product { Name="A" Priority="4" Value=null };
Product five = new Product { Name="A" Priority="5" Value="20" };
Product six = new Product { Name="A" Priority="6" Value=null };

在示例中,我需要首先根据产品的优先级对产品列表进行排序,然后检查第一个非空值(即优先级 3)和最后一个非空值(即优先级 5),然后获取优先级 3 和 5 内具有空值的所有产品的列表。因此,在我们的示例中,只有具有优先级 4 的产品 4 是我要查找的记录。 我实际上是按产品对它们进行分组并按优先级对其进行排序,但在此之后仍然坚持如何进行

from p in Products
group p by p.Product into grp
select new
{
   Product = grp.Key
   Values = grp.OrderBy(x => x.Priority)
}

有人可以指点我如何进行吗?我在想我可以使用索引来识别所有非空值并遍历以获取最小和最大优先级值,然后查询所有在最小/最大优先级内具有空白空值的记录。

【问题讨论】:

    标签: linq group-by sql-order-by


    【解决方案1】:

    如果您确定哪些值是您在组中的起点和终点并从那里过滤,这将更容易和更有效。

    var query =
        from product in Products
        group product by product.Name into g
        let ordered = g.OrderBy(p => p.Priority).ToList()
        let firstIndex = ordered.FindIndex(p => p.Value != null)
        let lastIndex = ordered.FindLastIndex(p => p.Value != null)
        select new
        {
            Product = g.Key,
            Values = ordered
                .Skip(firstIndex + 1)
                .Take(lastIndex - firstIndex - 1)
                .Where(p => p.Value == null),
        };
    

    【讨论】:

      【解决方案2】:

      怎么样(您可以使用.Select 而不是.SelectMany 为每个产品获取单独的组。.SelectMany 将所有有效的结果记录组合到一个列表中):

      Products
          .GroupBy(p => p.Name)
          .SelectMany (grp =>
              grp.OrderBy(p => p.Priority)           // sort by priority
                  .SkipWhile(p => p.Value == null)   // skip null entries at beginning
                  .Reverse()                         // reverse
                  .SkipWhile(p => p.Value == null)   // skip null entries at end
                  .Reverse()                         // reverse back to normal
                  .Where(p => p.Value == null)       // then find null entries
          );
      

      演示:http://ideone.com/2dU9L

      【讨论】:

      • 看起来很接近,但您错过了GroupBy
      • @MarkByers:我已经添加了GroupBy
      • @mellamokb 非常感谢您的快速回复。当我尝试这个查询时,我得到一个异常,例如“至少一个对象必须实现 IComparable”。这个其实是针对LinqToDataSet的,不知道有没有区别。
      • 没关系。我错过了一些演员,这一切似乎都很好。再次感谢
      • 哎呀,那会非常非常低效。
      猜你喜欢
      • 2019-01-07
      • 1970-01-01
      • 2011-05-05
      • 2010-09-07
      • 2011-10-08
      • 2020-02-02
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      相关资源
      最近更新 更多