Linq:双值列表 - 后继值之间的差异

时间:2009-03-06 15:05:30

标签: c# linq list double

我有一个双重值列表......

1.23,1.24,1.78,1,74 ......

所以我想计算后继者之间的差异 - >只添加(负值应首先为正)...以上4个值将为0,01 +0,53( - ) - 0,04 ( - ) - >使它成为积极的......

使用for循环,很容易......任何想法如何用linq解决它?

2 个答案:

答案 0 :(得分:6)

我不确定你对负面的意思是什么,但这可能会做你想要的。这很糟糕,因为它使用副作用,但是......

double prev = 0d;
var differences = list.Select(current =>
    {
       double diff = prev - current;
       prev = current;
       return Math.Abs(diff);
    }).Skip(1);

(跳过第一个值,因为它只是给出了第一个原始值和0d之间的差异。)

编辑:根据元素对进行投影的扩展方法可能稍微好一些。这会将副作用隔离在一个地方,这很好:

using System.Collections.Generic;

// This must be a non-nested type, and must be static to allow the extension
// method.
public static class Extensions
{
    public static IEnumerable<TResult> SelectPairs<TSource, TResult>
        (this IEnumerable<TSource> source,
         Func<TSource, TSource, TResult> selector)
    {
        using (IEnumerator<TSource> iterator = source.GetEnumerator())
        {
           if (!iterator.MoveNext())
           {
               yield break;
           }
           TSource prev = iterator.Current;
           while (iterator.MoveNext())
           {
               TSource current = iterator.Current;
               yield return selector(prev, current);
               prev = current;
           }
        }
    }
}

要在特定情况下使用此功能,您需要:

var differences = list.SelectPairs((x, y) => Math.Abs(x-y));

答案 1 :(得分:2)

您可以使用为函数提供索引的Select方法的重载,以便您可以访问数组中的先前值:

double sum = values.Skip(1).Select((n, i) => Math.Abs(n - values[i])).Sum();

不是一个完美的“干净”LINQ解决方案(Jon的SelectPairs扩展看起来更好),但我认为这是形成配对的最简单方法。