C#:SkipLast实现
我需要一种方法来提供序列中除了最后一项以外的所有内容。这是我当前的实现:C#:SkipLast实现,c#,extension-methods,ienumerable,implementation,C#,Extension Methods,Ienumerable,Implementation,我需要一种方法来提供序列中除了最后一项以外的所有内容。这是我当前的实现: public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source) { using (IEnumerator<T> iterator = source.GetEnumerator()) { if(iterator.MoveNext())
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;
}
}
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
使用(IEnumerator迭代器=source.GetEnumerator())
{
if(iterator.MoveNext())
while(true)
{
var current=迭代器.current;
如果(!iterator.MoveNext())
屈服断裂;
产生回流电流;
}
}
}
我需要它的目的是对除最后一项之外的所有项目进行处理。在我的例子中,我有一系列具有各种属性的对象。然后我按日期订购,然后我需要对所有商品进行调整,但最近的商品除外(这将是订购后的最后一个)
问题是,我还不太喜欢这些枚举器之类的东西,这里也没有人问:p我想知道的是,这是一个好的实现,还是我在某个地方犯了一个小错误或大错误。或者,也许这个问题是个奇怪的问题,等等
我想更一般的实现可能是
AllExceptMaxBy
方法。因为事实就是这样。有一个MaxBy
和MinBy
方法,我的方法也需要这样做,但返回除最大值或最小值之外的所有项。您的实现在我看来非常好-这可能是我的方法
关于你的情况,我建议的唯一简化方法是将列表按相反的顺序排列(即升序而不是降序)。虽然这可能不适合您的代码,但它允许您简单地使用collection.Skip(1)
获取除最近的项目外的所有项目
如果由于您未在帖子中显示的原因而无法实现,那么您当前的实现就没有问题。您的实现在我看来非常好-这可能是我会采用的方式 关于你的情况,我建议的唯一简化方法是将列表按相反的顺序排列(即升序而不是降序)。虽然这可能不适合您的代码,但它允许您简单地使用
collection.Skip(1)
获取除最近的项目外的所有项目
如果由于您未在帖子中展示的原因而无法实现,那么您当前的实现根本没有问题。这是一个棘手的问题,因为“最后一个元素”不是马尔可夫停止点:在尝试获取下一个元素之前,您无法判断您已经到达了最后一个元素。这是可行的,但前提是你不介意永远“落后一方”。这基本上就是您当前的实现所做的,它看起来还不错,尽管我可能会写一些不同的东西
另一种方法是使用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;
}
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
T先前=默认值(T);
bool first=true;
foreach(源中的T元素)
{
如果(!第一个)
{
以前的收益率;
}
先前=元素;
第一个=假;
}
}
另一个选项,更接近您的代码:
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;
}
}
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
使用(IEnumerator迭代器=source.GetEnumerator())
{
如果(!iterator.MoveNext())
{
屈服断裂;
}
T previous=迭代器.Current;
while(iterator.MoveNext())
{
以前的收益率;
previous=迭代器.Current;
}
}
}
这避免了嵌套太深(如果序列为空,则提前退出),并使用“real”while条件而不是while(true)
这很棘手,因为“last element”不是马尔可夫停止点:在尝试获取下一个元素之前,无法判断您已经到达了最后一个元素。这是可行的,但前提是你不介意永远“落后一方”。这基本上就是您当前的实现所做的,它看起来还不错,尽管我可能会写一些不同的东西
另一种方法是使用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;
}
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
T先前=默认值(T);
bool first=true;
foreach(源中的T元素)
{
如果(!第一个)
{
以前的收益率;
}
先前=元素;
第一个=假;
}
}
另一个选项,更接近您的代码:
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;
}
}
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
使用(IEnumerator迭代器=source.GetEnumerator())
{
如果(!iterator.MoveNext())
{
屈服断裂;
}
T previous=迭代器.Current;
while(iterator.MoveNext())
{
以前的收益率;
previous=迭代器.Current;
}
}
}
这避免了嵌套太深(如果序列为空,则提前退出),并使用“real”while条件而不是
while(true)
如果使用.NET 3.5,我想您可以使用:
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
{
return source.TakeWhile((item, index) => index < source.Count() - 1))
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
返回source.TakeWhile((项,索引)=>index
如果您使用的是.NET 3.5,我想您可以使用:
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
{
return source.TakeWhile((item, index) => index < source.Count() - 1))
}
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
返回source.TakeWhile((项,索引)=>index
公共静态IEnumerable SkipLast(此IEnumerable源代码)
{
如果(!source.Any())
{
屈服断裂;
}
队列项目=新队列();
items.Enqueue(source.First());