2009-03-06 2 views
4

У меня есть список двойных значений ...Linq: Список двойных значений - различия между преемником значением

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

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

с петлей, легко ... любая идея, как ее решить с помощью linq?

+0

Почему? Зачем это решать с LINQ? Это не похоже на проблему, которая должна быть решена с помощью LINQ. –

+0

Почему 0.53 вместо 0.54 в вашем примере? –

ответ

6

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

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

(первое значение пропускается, поскольку он просто дает разницу между первым первоначальной стоимостью и 0D.)

EDIT: Что может быть немного более приятным был бы метод расширения для проекта, основанный на парах элементов. Это изолирует побочные эффекты в одном месте, что это хорошо:

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)); 
+0

он подчеркивает это мной (этот IEnumerable & current из отредактированной функции ..., что означает ошибку :-( – 2009-03-06 15:32:32

+0

Это поможет, если вы можете опубликовать сообщение об ошибке, а не только то, что оно подчеркивает это, но я подозреваю, что у вас нет поместите сообщение расширения в статический тип верхнего уровня. –

+0

i belive это так ... потому что я не знаю, как ... – 2009-03-06 15:51:03

2

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

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

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

+0

Это работает только в том случае, если значения реализуют IList , а не только IEnumerable . Возможно, все в порядке. –