【问题标题】:How to use LINQ select in one column with condition如何在有条件的一列中使用 LINQ 选择
【发布时间】:2016-01-25 18:53:34
【问题描述】:

这样的数据表...

Date       Count
20160101   100
20160102   103
20160103   108
20160104   102
20160105   104
20160106   106
20160107   108

我要select if => someday.Count > someday[-3].Count

结果 = 以下 3 行:

20160104,因为102>100
20160105,因为104>103
20160107,因为108>102

请告诉我如何使用 LINQ?
非常感谢

【问题讨论】:

  • 您能否澄清您的问题,或者使用不同的措辞?很难理解你想要什么。

标签: c# linq select


【解决方案1】:

一种方法是这样做。

int index = 0;
var a = from i in someday
        let indexNow = index++
        where indexNow >= 3
        let j = someday[indexNow - 3]
        where i.Count > j.Count
        select i;

您创建临时变量 j 以在三个步骤之前获取元素,然后将其与当前元素进行比较以检查它是否满足特定条件。如果是,则选择它

【讨论】:

    【解决方案2】:

    使用索引的Where-overload 如下:

    var result = myDates.Where((x, index) => index >= 3 && x > myDates.ElementAt(x - 3).Count);
    

    这会从您的集合中选择所有那些比三天前的元素中计数更多的元素。

    【讨论】:

      【解决方案3】:

      您可以使用Where 重载,它将Func<TSource, int, bool> predicate 作为输入。此委托的第二个输入是当前元素的索引。因此,这意味着您的 lambda 表达式必须接受两个输入,第一个是元素的类型,另一个是 Int32Where 方法会自动计算当前元素的索引。

      var result = myColl.Where((x, index) => index >= 3 && x.Count > myColl.ElementAt(index - 3).Count);
      

      然后您可以使用您想要的方法,如Select()ToList() 等。

      PS:我假设对象的名称是myColl

      另外:

      我总是喜欢告诉开发者http://referencesource.microsoft.com/。您可以轻松找到所有方法的实现以及有关 C# 源代码的所有内容。 如果您有兴趣,这里是Where 方法重载的源代码。

          public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
              if (source == null) throw Error.ArgumentNull("source");
              if (predicate == null) throw Error.ArgumentNull("predicate");
              return WhereIterator<TSource>(source, predicate);
          }
      

      如您所见,它将返回WhereIterator,它会自动计算当前项目的索引并将其发送到您的方法:

      static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
          int index = -1;
          foreach (TSource element in source) {
              checked { index++; }
              if (predicate(element, index)) yield return element;
          }
      }
      

      【讨论】:

        【解决方案4】:

        虽然其他答案中描述的索引技术将起作用,但如果源序列不是基于列表的,它们将效率低下,在这种情况下ElementAt 将导致 O(N^2) 时间复杂度操作。

        只有 O(N) 时间复杂度(如果源序列本身不包含繁重的操作)的一种可能更好的方法是使用 SkipZip 的组合,像这样

        var result = myDates
            .Skip(3)
            .Zip(myDates, (current, compare) => current.Count > compare.Count ? current : null)
            .Where(item => item != null);
        

        【讨论】:

          猜你喜欢
          • 2016-04-06
          • 1970-01-01
          • 1970-01-01
          • 2012-09-06
          • 2020-08-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多