作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是问题的更一般形式,如何对列表的第一个和最后一个元素做一些特殊的事情?更具体的问题很容易回答。我们知道第一个和最后一个元素的索引,因此我们可以直接访问它们或根据这些值测试索引变量。例如:
for (int i = 0; i < values.Count; ++i)
{
if (i == values.Count - 1)
{
// do something with last element
}
else
{
// do something else
}
}
但有时我需要用 IEnumerable<T>
做一些变体。例如:
public static Bar TransformFoo(Foo value)
{
if (isLast /* how do we know this? */)
{
// do something with the last element
}
else
{
// do something else
}
}
public static IEnumerable<Bar> TransformFooSequence(IEnumerable<Foo> source)
{
return source.Select(TransformFoo);
}
由于这是一种常见模式,因此我想以通用方式解决它(而不是像过去那样为每种情况编写自定义 for 循环)。一种选择是使用 ToList()
将序列转换为列表。或使用 Count()
对元素进行计数。这两种情况的问题在于,解决方案涉及评估整个序列,这可能会非常昂贵。
所以问题是,我如何评估 IEnumerable<T>
序列,同时对其第一个和/或最后一个元素进行特殊处理,同时以一般方式保持该序列的惰性评估?
最佳答案
解决此问题的一种方法是为 IEnumerable<T>
创建一个新的扩展方法返回源序列的元素以及有关其位置的语义信息。如果源序列的元素具有类型 T
,那么扩展方法将返回 (T, PositionFlags)
类型的元组。代码如下:
[Flags]
enum PositionFlags
{
None = 0,
First = 1,
Last = 2
}
public static IEnumerable<(T value, PositionFlags flags)> WithPositions<T>(
this IEnumerable<T> source)
{
using (var enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
{
yield break;
}
T value = enumerator.Current;
PositionFlags flags = PositionFlags.First;
while (enumerator.MoveNext())
{
yield return (value, flags);
value = enumerator.Current;
flags = PositionFlags.None;
}
flags |= PositionFlags.Last;
yield return (value, flags);
}
}
然后,我们可以传递位置信息,以对序列中的第一个和/或最后一个项目进行特殊处理。例如:
Bar TransformFoo(Foo value, bool isLast)
{
if (isLast)
{
// do something with the last element
}
else
{
// do something else
}
}
IEnumerable<Bar> TransformFooSequence(IEnumerable<Foo> source)
{
return source
.WithPositions()
.Select(entry => TransformFoo(
entry.value,
(entry.flags & PositionFlags.Last) == PositionFlags.Last));
}
关于c# - 如何在对 C# 中的第一个和/或最后一个元素进行特殊处理的同时评估 IEnumerable<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52460974/
我是一名优秀的程序员,十分优秀!