2010-09-21 6 views
0

J'ai quelque chose comme ceci:LINQ globale pour retourner tableau de valeurs

long[] f = new long[4]{1,10,100,1000}; 

Je veux diviser 1000 par 100, 100 par 10 et 10 par 1

est-il un moyen de retourner des résultats dans un tableau avec les résultats, par exemple/10,10,10

MISE à JOUR: Cela semble confondre quelques voici donc un autre exemple

à long [] f = new temps [ 3] {1,2,6};

Je veux diviser 6 par 2 et 2 par 1 avec les résultats dans un tableau

+0

L'énoncé de question n'est pas clair pour moi. Voulez-vous diviser chaque élément à la puissance correspondante de dix? (10^i). Diviser par l'élément précédent? Dans ce cas, que voulez-vous qu'il se passe dans le cas de la division zéro? –

Répondre

0

solution simple sans utiliser LINQ:

IEnumerable<long> GetResults(long[] input) 
    { 
     for (int i = input.Length -1; i >= 1; --i) 
      yield return input[i]/input[i - 1]; 
    } 

Vous pouvez utiliser LINQ sur la valeur de retour difficile et il fonctionne dans .NET 3.5 :)

+1

Bien que cette implémentation fonctionnera, elle nécessite que l'entrée soit directement accessible. Une solution générique "IEnumerable" doit être préférée. – xtofl

+0

Eh bien, ma solution résout le problème et il est très compact. Je ne vois pas pourquoi quelqu'un aurait moins une solution de travail - c'est ridicule. N'importe qui peut fournir une meilleure alternative s'il en connaît. – testalino

+0

@xtofl: Le type de paramètre peut être modifié en ReadOnlyCollection . Mais la solution de testalino est toujours le fichier. – Liton

4

Je ne pense pas que l'aide globale est va dans ce cas ... Zip serait mieux adapté:

long[] f = new long[4]{1,10,100,1000}; 
long[] result = f.Skip(1).Zip(f, (a, b) => a/b); 

EDIT: si vous êtes sur .NET 3.5, vous pouvez facilement écrire une méthode d'extension Zip vous:

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector) 
    { 

     if (first == null) 
      throw new ArgumentNullException("first"); 
     if (second == null) 
      throw new ArgumentNullException("second"); 
     if (selector == null) 
      throw new ArgumentNullException("selector"); 

     return first.ZipIterator(second, selector); 
    } 

    private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector) 
    { 
     using (var enum1 = first.GetEnumerator()) 
     using (var enum2 = second.GetEnumerator()) 
     { 
      while (enum1.MoveNext() && enum2.MoveNext()) 
      { 
       yield return selector(enum1.Current, enum2.Current); 
      } 
     } 
    } 
+0

J'ai seulement .Net 3.5 – Jon

+0

Voir ma mise à jour –

3

Si je vous comprends bien, vous ne voulez probablement pas utiliser Aggregate ici, mais à la place Pairwise:

long[] result = f.Pairwise((x, y) => y/x).ToArray(); 

Voici un exemple d'implémentation de par paires:

public static IEnumerable<TResult> Pairwise<TSource, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, TSource, TResult> resultSelector) 
{ 
    TSource previous = default(TSource); 

    using (var it = source.GetEnumerator()) 
    { 
     if (it.MoveNext()) 
      previous = it.Current; 

     while (it.MoveNext()) 
      yield return resultSelector(previous, previous = it.Current); 
    } 
} 

Source

Si vous voulez les résultats dans l'ordre inverse puis ajoutez un appel à Reverse.

Questions connexes