在迭代时是否有Linq方式知道序列中的下一个元素是什么?作为一个具体的例子,假设我有一个整数列表,我想计算每个元素与其后继元素之间的差异,所以例如我希望能够写出
var myList = new List<int>() { 1,3,8,2,10 };
var differences = myList.Select( ml => ml.Next() - ml ) // pseudo-code, obviously
我想要的结果是列表{2,5,-6,8}。
显然这在for循环中是微不足道的,但是有人可以想到Linq中的一个简洁的单行程来完成这项工作吗?
答案 0 :(得分:37)
var differences = myList.Zip(myList.Skip(1), (x, y) => y - x);
如果您使用的是旧版本的框架,并且/或者您希望稍微更有效地执行此操作,那么您可以创建一个简单的扩展方法:
var differences = myList.Pairwise((x, y) => y - x);
// ...
public static class EnumerableExtensions
{
public static IEnumerable<T> Pairwise<T>(
this IEnumerable<T> source, Func<T, T, T> selector)
{
if (source == null) throw new ArgumentNullException("source");
if (selector == null) throw new ArgumentNullException("selector");
using (var e = source.GetEnumerator())
{
if (!e.MoveNext()) throw new InvalidOperationException("Sequence cannot be empty.");
T prev = e.Current;
if (!e.MoveNext()) throw new InvalidOperationException("Sequence must contain at least two elements.");
do
{
yield return selector(prev, e.Current);
prev = e.Current;
} while (e.MoveNext());
}
}
}
答案 1 :(得分:5)
var differences = myList
.Take(myList.Count - 1)
.Select((v, i) => myList[i + 1] - v);
假设该列表至少有2个项目。