Svi*_*ish 1 c# ienumerable implementation extension-methods
我需要一个方法来给我所有但序列中的最后一项.这是我目前的实施:
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if(iterator.MoveNext())
while(true)
{
var current = iterator.Current;
if(!iterator.MoveNext())
yield break;
yield return current;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我需要的是对除了最后一项之外的所有项目做一些事情.在我的例子中,我有一系列具有各种属性的对象.然后我按日期订购它们,然后我需要对所有这些进行调整,除了最近的项目(这将是订购后的最后一项).
事实上,我对这些调查员和其他东西都不太了,也没有任何人在这里问过:p我想知道的是,如果这是一个很好的实现,或者我在某个地方做了一个小错误或大错.或者,如果可能这个问题是一个奇怪的,等等.
我想更通用的实现可能是一种AllExceptMaxBy方法.因为那就是它的本质.该MoreLinq有一个MaxBy和MinBy方法,我的方法种类需要做的是相同的,但返回的每一项除了最大或最小的一个.
这很棘手,因为"最后一个元素"不是马尔可夫的停止点:你不能告诉你到最后一个元素,直到你试图获得下一个元素.这是可行的,但只有你不介意永远是"背后的一个元素".这基本上是你当前的实现,它看起来没问题,虽然我可能会略有不同.
另一种方法是使用foreach,总是产生先前返回的值,除非您在第一次迭代时:
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
{
T previous = default(T);
bool first = true;
foreach (T element in source)
{
if (!first)
{
yield return previous;
}
previous = element;
first = false;
}
}
Run Code Online (Sandbox Code Playgroud)
另一种选择,更接近您的代码:
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if(!iterator.MoveNext())
{
yield break;
}
T previous = iterator.Current;
while (iterator.MoveNext())
{
yield return previous;
previous = iterator.Current;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样可以避免嵌套(如果序列为空则通过提前退出)并且它使用"真实"而不是条件而不是 while(true)