不要在linq C#中取得最新记录

时间:2019-07-06 10:41:23

标签: c# linq

我们都知道Skip()可以省略收集开始时不需要的记录。

但是有没有办法在集合的末尾Take()记录?

您如何不采集集合中的最后一条记录?

还是您必须通过var collection = MyCollection var listCount = collection.Count(); var takeList = collection.Take(listCount - 1);

即下面的代码

npm install @angular-devkit/build-angular@0.13.4 --save-dev

这是排除集合中最后一条记录的唯一方法吗?

4 个答案:

答案 0 :(得分:4)

使用枚举器,您可以通过一个枚举有效地延迟收益。

public static IEnumerable<T> WithoutLast<T>(this IEnumerable<T> source)
{
    using (IEnumerator<T> e = source.GetEnumerator()) 
    {
        if (e.MoveNext() == false) yield break;

        var current = e.Current;
        while (e.MoveNext())
        {
            yield return current;
            current = e.Current;
        }
    }   
}

用法

var items = new int[] {};
items.WithoutLast(); // returns empty

var items = new int[] { 1 };
items.WithoutLast(); // returns empty

var items = new int[] { 1, 2 };
items.WithoutLast(); // returns { 1 }

var items = new int[] { 1, 2, 3 };
items.WithoutLast(); // returns { 1, 2 }

答案 1 :(得分:3)

那呢:

static public IEnumerable<T> SkipLast<T>(this IEnumerable<T> data, int count)
{
  if (data == null || count < 0) yield break;

  Queue<T> queue = new Queue<T>(data.Take(count));

  foreach (T item in data.Skip(count))
  {
    queue.Enqueue(item);
    yield return queue.Dequeue();
  }
}

更新

在某些reviews的帮助下,基于同一构想的优化版本可能是:

static public IEnumerable<T> SkipLast<T>(this IEnumerable<T> data, int count)
{
  if (data == null) throw new ArgumentNullException(nameof(data));
  if (count <= 0) return data;

  if (data is ICollection<T> collection)
    return collection.Take(collection.Count - count);

  IEnumerable<T> Skipper()
  {
    using (var enumer = data.GetEnumerator())
    {
      T[] queue = new T[count];
      int index = 0;

      while (index < count && enumer.MoveNext())
        queue[index++] = enumer.Current;

      index = -1;
      while (enumer.MoveNext())
      {
        index = (index + 1) % count;
        yield return queue[index];
        queue[index] = enumer.Current;
      }
    }
  }

  return Skipper();
}

答案 2 :(得分:3)

亨里克·汉森(Henrik Hansen)的answer的稍有不同:

static public IEnumerable<TSource> SkipLast<TSource>(
    this IEnumerable<TSource> source, int count)
{
    if (count < 0) count = 0;
    var queue = new Queue<TSource>(count + 1);
    foreach (TSource item in source)
    {
        queue.Enqueue(item);
        if (queue.Count > count) yield return queue.Dequeue();
    }
}

答案 3 :(得分:1)

一种方法是:

var result = l.Reverse().Skip(1);

如果需要的话,再进行一次反向操作,以恢复原始顺序。