Linq: список двойных значений - различия между последующими значениями - PullRequest
4 голосов
/ 06 марта 2009

у меня есть список двойных значений ...

1,23, 1,24, 1,78, 1,74 ...

поэтому я хочу рассчитать разницу между преемником -> только добавление (отрицательные значения должны быть в первую очередь положительными) ... выше 4 значений будет 0,01 +0,53 (-) - 0,04 (-) -> сделать его позитивным ...

с циклом for, это легко ... есть идеи, как решить эту проблему с помощью linq?

Ответы [ 2 ]

6 голосов
/ 06 марта 2009

Я не уверен, что вы имеете в виду относительно отрицательных битов, но это может сделать то, что вы хотите. Это ужасно, потому что он использует побочные эффекты, но ...

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));
2 голосов
/ 06 марта 2009

Вы можете использовать перегрузку метода Select, который предоставляет индекс функции, чтобы вы могли получить доступ к предыдущему значению в массиве:

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

Не совсем «чистое» решение LINQ (расширение Jon's SelectPairs выглядит лучше), но я думаю, что это самый простой способ для формирования пар.

...