当前位置:  开发笔记 > 小程序 > 正文

我可以使用LINQ仅检索"on change"值吗?

如何解决《我可以使用LINQ仅检索"onchange"值吗?》经验,为你挑选了1个好方法。

我希望能够做的是构建一个LINQ查询,当其中一个字段发生变化时,它会从某些DataRows中检索一些值.这是一个人为的例子来说明:

Observation   Temp  Time
------------- ----  ------
Cloudy        15.0  3:00PM
Cloudy        16.5  4:00PM
Sunny         19.0  3:30PM
Sunny         19.5  3:15PM
Sunny         18.5  3:30PM
Partly Cloudy 16.5  3:20PM
Partly Cloudy 16.0  3:25PM
Cloudy        16.0  4:00PM
Sunny         17.5  3:45PM

当观察从前一个观察发生变化时,我只想检索条目.所以结果将包括:

Cloudy        15.0  3:00PM
Sunny         19.0  3:30PM
Partly Cloudy 16.5  3:20PM
Cloudy        16.0  4:00PM
Sunny         17.5  3:45PM

目前有代码迭代DataRows并进行结果的比较和构建,但希望使用LINQ来实现这一目标.

我想做的是这样的事情:

var weatherStuff = from row in ds.Tables[0].AsEnumerable()
                   where row.Field("Observation") != weatherStuff.ElementAt(weatherStuff.Count() - 1) )
                   select row;

但这不起作用 - 并且不会编译,因为它在声明之前尝试使用变量'weatherStuff'.

可以用LINQ做我想做的事吗?我在SO上没有看到像这样的另一个问题,但可能错过了它.



1> Tomas Petric..:

这是一个更普遍的想法,可能是相互影响.它比@tvanfosson发布的更复杂,但在某种程度上,我觉得它更优雅:-).您要执行的操作是使用第一个字段对观察结果进行分组,但是每次值更改时您都希望启动一个新组.然后,您要选择每个组的第一个元素.

这听起来几乎像LINQ,group by但它有点不同,所以你不能真正使用标准group by.但是,您可以编写自己的版本(这是LINQ的奇迹!).您可以编写自己的扩展方法(例如GroupByMoving),也可以编写将类型更改IEnumerable为某个接口的扩展方法,然后GroupBy为此接口定义.生成的查询将如下所示:

var weatherStuff = 
  from row in ds.Tables[0].AsEnumerable().AsMoving()
  group row by row.Field("Observation") into g
  select g.First();

唯一剩下的就是定义AsMoving和实施GroupBy.这有点工作,但它通常是有用的东西,它也可以用来解决其他问题,所以它可能值得这样做:-).我的帖子的摘要是关于LINQ的好处是你可以自定义操作符的行为以获得非常优雅的代码.

我没有测试过,但实现应该如下所示:

// Interface & simple implementation so that we can change GroupBy
interface IMoving : IEnumerable { }
class WrappedMoving : IMoving {
  public IEnumerable Wrapped { get; set; }
  public IEnumerator GetEnumerator() { 
    return Wrapped.GetEnumerator(); 
  }
  public IEnumerator GetEnumerator() { 
    return ((IEnumerable)Wrapped).GetEnumerator(); 
  }
}

// Important bits:
static class MovingExtensions { 
  public static IMoving AsMoving(this IEnumerable e) {
    return new WrappedMoving { Wrapped = e };
  }

  // This is (an ugly & imperative) implementation of the 
  // group by as described earlier (you can probably implement it
  // more nicely using other LINQ methods)
  public static IEnumerable> GroupBy(this IEnumerable source, 
       Func keySelector) {
    List elementsSoFar = new List();
    IEnumerator en = source.GetEnumerator();
    if (en.MoveNext()) {
      K lastKey = keySelector(en.Current);
      do { 
        K newKey = keySelector(en.Current);
        if (newKey != lastKey) { 
          yield return elementsSoFar;
          elementsSoFar = new List();
        }
        elementsSoFar.Add(en.Current);
      } while (en.MoveNext());
      yield return elementsSoFar;
    }
  }

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有