如何访问 IQueryable中的连续元素 目的?

发布于 2024-07-16 17:52:32 字数 250 浏览 3 评论 0原文

我需要访问 IQueryable 对象中的当前和上一个元素。 如果我有一个 int 数组,我会执行以下操作:

var array = new int[]{0,1,2,3,4};
for(var i = 1; i<array.Length ; i++)
{
    method1(array[i-1], array[i]);
}

我不知道对 IQueryable 执行相同的操作,因为它没有实现 IList。

I need to access the current and previous element in an IQueryable object. If I had an int array, I would do the following:

var array = new int[]{0,1,2,3,4};
for(var i = 1; i<array.Length ; i++)
{
    method1(array[i-1], array[i]);
}

I don't know to do the same with IQueryable, since it does not implement IList.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅笑轻吟梦一曲 2024-07-23 17:52:33

使用扩展方法使这变得相当容易。

public static class IEnumerableExtensions
{
  public static IEnumerable<ValueWithPrevious<T>> WithPrevious<T>(this IEnumerable<T> @this)
  {
    using (var e = @this.GetEnumerator())
    {
      if (!e.MoveNext())
        yield break;

      var previous = e.Current;

      while (e.MoveNext())
      {
        yield return new ValueWithPrevious<T>(e.Current, previous);
        previous = e.Current;
      }
    }
  }
}

public struct ValueWithPrevious<T>
{
  public readonly T Value, Previous;

  public ValueWithPrevious(T value, T previous)
  {
    Value = value;
    Previous = previous;
  }
}

用法:

var array = new int[] { 1, 2, 3, 4, 5 };
foreach (var value in array.WithPrevious())
{
  Console.WriteLine("{0}, {1}", value.Previous, value.Value);
  // Results: 1, 2
  //          2, 3
  //          3, 4
  //          4, 5
}

Using extension methods makes this fairly easy.

public static class IEnumerableExtensions
{
  public static IEnumerable<ValueWithPrevious<T>> WithPrevious<T>(this IEnumerable<T> @this)
  {
    using (var e = @this.GetEnumerator())
    {
      if (!e.MoveNext())
        yield break;

      var previous = e.Current;

      while (e.MoveNext())
      {
        yield return new ValueWithPrevious<T>(e.Current, previous);
        previous = e.Current;
      }
    }
  }
}

public struct ValueWithPrevious<T>
{
  public readonly T Value, Previous;

  public ValueWithPrevious(T value, T previous)
  {
    Value = value;
    Previous = previous;
  }
}

Usage:

var array = new int[] { 1, 2, 3, 4, 5 };
foreach (var value in array.WithPrevious())
{
  Console.WriteLine("{0}, {1}", value.Previous, value.Value);
  // Results: 1, 2
  //          2, 3
  //          3, 4
  //          4, 5
}
心作怪 2024-07-23 17:52:33

您可以将 IQueryable<> 进入列表<> 使用 ToList<>()。

You can turn an IQueryable<> into a List<> using ToList<>().

遥远的绿洲 2024-07-23 17:52:33

编辑

有点误读了这个问题。 这段代码将为您提供后续元素,

public static IEnumerable<Pair<T,T>> GroupIntoConsequetive(this IEnumerable<T> enumerable) {
  using ( var e = enumerable.GetEnumerator() ) {
    if ( !e.MoveNext() ) { 
      yield break;
    }
    var last = e.Current;
    while ( e.MoveNext() ) {
      yield return new Pair<T,T>(last, e.Current);
      last = e.Current;
    }
  }
}

我不确定是否有默认方法,但编写扩展方法来执行此操作应该不会太困难。 我假设有一个简单的 Pair 实现

public static IEnumerable<Pair<T,T>> Window(this IEnumerable<T> enumerable) {
  using ( var e = enumerable.GetEnumerator() ) {
    while ( e.MoveNext() ) { 
      var first = e.Current;
      if ( !e.MoveNext() ) {
        throw new InvalidOperationException("Need even number");
      }
      var second = e.Current;
      yield return new Pair<T,T>(first,second);
   }
  }
}

通过窗口,您可以通过以下

var col = GetQueryableItem();
col.Window().Select(pair => method1(pair.First, pair.Second));

快速和肮脏的 Pair 实现获得您想要的行为

public struct Pair<T1,T2> {
  public readonly T1 First;
  public readonly T2 Second;
  public Pair(T1 first, T2 second) {
    First = first;
    Second = second;
  }
}

EDIT

Misread the question a bit. This code will give you consequetive elements

public static IEnumerable<Pair<T,T>> GroupIntoConsequetive(this IEnumerable<T> enumerable) {
  using ( var e = enumerable.GetEnumerator() ) {
    if ( !e.MoveNext() ) { 
      yield break;
    }
    var last = e.Current;
    while ( e.MoveNext() ) {
      yield return new Pair<T,T>(last, e.Current);
      last = e.Current;
    }
  }
}

I'm not sure there is default way but writing an extension method to do so shouldn't be to difficult. I'm assuming there is a simple Pair implementation

public static IEnumerable<Pair<T,T>> Window(this IEnumerable<T> enumerable) {
  using ( var e = enumerable.GetEnumerator() ) {
    while ( e.MoveNext() ) { 
      var first = e.Current;
      if ( !e.MoveNext() ) {
        throw new InvalidOperationException("Need even number");
      }
      var second = e.Current;
      yield return new Pair<T,T>(first,second);
   }
  }
}

With the window you could then get the behavior you desire with the following

var col = GetQueryableItem();
col.Window().Select(pair => method1(pair.First, pair.Second));

Quick and dirty Pair implementation

public struct Pair<T1,T2> {
  public readonly T1 First;
  public readonly T2 Second;
  public Pair(T1 first, T2 second) {
    First = first;
    Second = second;
  }
}
我不吻晚风 2024-07-23 17:52:33

但它提供了扩展方法来从 IQueryable 实例创建数组或列表,请参阅ToArray()ToList()。 然后,您可以对示例中的数组执行相同的操作。

But it provides extension methods to create an array or a list from your IQueryable<T> instance, see ToArray() and ToList(). You can then go and do the same as you would with the array in your example.

一身骄傲 2024-07-23 17:52:33

IQueryable 是 IEnumerable。 所以你可以这样做:

var a = new [] {1, 2, 3, 4}.AsQueryable();

if (a.Count() < 2) {
    return;
}

var prev = a.First();
var isFirst = true;

foreach (var i in a) {
    if (isFirst) {
        isFirst = false;
        continue;
    }

    method1(prev, i);
    prev = i;
}

或者简单地将 IQueryable 转换为 IList:

var list = a.ToList();

IQueryable is IEnumerable. So you can do something like:

var a = new [] {1, 2, 3, 4}.AsQueryable();

if (a.Count() < 2) {
    return;
}

var prev = a.First();
var isFirst = true;

foreach (var i in a) {
    if (isFirst) {
        isFirst = false;
        continue;
    }

    method1(prev, i);
    prev = i;
}

Or simply convert IQueryable into IList:

var list = a.ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文