2009-03-06 6 views
4
successeur

j'ai une liste de valeurs doubles ...Linq: Liste des valeurs doubles - différences entre les valeurs

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

donc je veux calculer la différences entre le successeur -> ajout seulement (les valeurs négatives doivent être d'abord positives) ... au-dessus de 4 valeurs serait 0,01 +0,53 (-) - 0,04 (-) -> pour le rendre positif .. Avec une boucle for, c'est facile ... aucune idée comment le résoudre avec linq?

+0

Pourquoi? Pourquoi le résoudre avec LINQ? Cela ne ressemble pas à un problème qui doit être résolu avec LINQ. –

+0

Pourquoi 0,53 au lieu de 0,54 dans votre exemple? –

Répondre

6

Je ne suis pas sûr de savoir ce que vous voulez dire sur les bits négatifs, mais cela pourrait faire ce que vous voulez. Il est horrible, car il utilise des effets secondaires, mais ...

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

(La première valeur est ignorée, car il donne juste la différence entre la première valeur d'origine et 0d.)

EDIT: Ce qui pourrait être légèrement plus agréable serait une méthode d'extension à projeter basée sur des paires d'éléments. Cela permet d'isoler les effets secondaires en un seul endroit, ce qui est bien:

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; 
      } 
     } 
    } 
} 

Pour utiliser dans votre cas particulier, vous feriez:

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

il me souligne cela de (ce IEnumerable & courant de la fonction éditée ... ce qui signifie faute :-( –

+0

Il serait utile si vous pouviez poster le message d'erreur plutôt que juste qu'il le souligne, mais je soupçonne que vous n'avez pas mettre le message d'extension dans un type statique de premier niveau –

+0

je crois qu'il est tellement ... parce que je ne sais pas comment ... –

2

Vous pouvez utiliser la surcharge de la méthode Select qui fournit l'indice à la fonction, afin que vous puissiez accéder à la valeur précédente dans le tableau:

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

Pas parfaitement « propre » solution LINQ (extension de SelectPairs de Jon semble plus agréable), mais je pense qu'il est le plus facile façon de former les paires.

+0

Cela ne fonctionne que si les valeurs implémente IList plutôt que simplement IEnumerable . Peut-être bien dans ce cas particulier. –