我们都知道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
这是排除集合中最后一条记录的唯一方法吗?
答案 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);
如果需要的话,再进行一次反向操作,以恢复原始顺序。