如果您运行的是 .NET 4.0,这应该可以正常工作:
var deltas = list.Zip(list.Skip(1), (current, next) => next - current);
除了多个枚举器之外,这是非常有效的;它应该适用于任何类型的序列。
这是 .NET 3.5 的替代方案:
var deltas = list.Skip(1)
.Select((next, index) => next - list[index]);
显然,这个想法只有在使用列表的索引器时才会有效。修改它以使用ElementAt 可能不是一个好主意:非IList<T> 序列将出现二次运行时。在这种情况下,编写自定义迭代器是一个很好的解决方案。
编辑:如果您不喜欢Zip + Skip(1) 的想法,那么编写这样的扩展(未经测试)可能在这些情况下有用:
public class CurrentNext<T>
{
public T Current { get; private set; }
public T Next { get; private set; }
public CurrentNext(T current, T next)
{
Current = current;
Next = next;
}
}
...
public static IEnumerable<CurrentNext<T>> ToCurrentNextEnumerable<T>(this IEnumerable<T> source)
{
if (source == null)
throw new ArgumentException("source");
using (var source = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
yield break;
T current = enumerator.Current;
while (enumerator.MoveNext())
{
yield return new CurrentNext<T>(current, enumerator.Current);
current = enumerator.Current;
}
}
}
然后你可以用作:
var deltas = list.ToCurrentNextEnumerable()
.Select(c=> c.Next - c.Current);