2010-02-24 13 views
3

J'utilise actuellement un foreach et j'ai besoin de l'index de l'élément.Index dans un Foreach

  foreach (DataRow m_row in base_rows) 
     { 
      Company nu = new Company(m_row, symb_rows[0]); 
     } 

Voici le code. J'essaye d'obtenir l'index de m_row à l'intérieur de base_rows et l'utilise pour passer symb_rows[index_of_m_row]. Est-ce possible ou dois-je simplement utiliser une boucle normale?

Répondre

11

La solution de boucle "for" est parfaitement claire. En tant que solution alternative intéressante, vous pouvez éviter la boucle tout à fait:

var companies = baseRows 
    .Select((row, index) => new Company(row, symbRows[index])) 
    .ToList(); 
+1

+1 Très intelligent :) –

+4

@Andrew: et donc probablement une mauvaise idée. Je n'aime pas le code intelligent. J'aime le code simple, ennuyeux, facile à lire et à comprendre qui n'exige aucune intelligence. Cette technique peut être utile dans les contextes où la sémantique de l'opération ressemble plus à une requête qu'à une transformation; Je pense que dans ce cas-ci, c'est excessif et qu'une boucle for serait probablement la meilleure solution. Vraiment, c'est à des fins de divertissement seulement. –

+0

Je comprends et suis entièrement d'accord. J'ai apprécié le divertissement bien! :) –

7

Afin de connaître votre indice actuel dans la collection (en utilisant un foreach), vous devez faire ceci:

Int32 i = 0; 
foreach (DataRow m_row in base_rows) 
{ 
    Company nu = new Company(m_row, symb_rows[i]); 
    i++; 
} 

ou utiliser une boucle for standard. L'interface IEnumerable n'expose pas une propriété d'index positionnelle car il s'agit d'un itérateur direct uniquement sur une séquence sous-jacente d'éléments.

+1

Oui, je voudrais simplement utiliser une boucle for, essayez d'utiliser GetLowerBound, GetUpperBound et vérifiez que chaque i est valide lorsque vous bouclez. – MindStalker

1

Vous devez utiliser une boucle normale ou créer votre propre compteur comme le suggère Andrew Hare pour que cela fonctionne. Je suggère d'utiliser une boucle for.

1

Une boucle for normale est le chemin à parcourir si vous avez besoin de l'index.

0

Je voudrais simplement utiliser une boucle normale.

Vous pourriez avoir un int les incréments chaque fois que vous bouclez autour mais un for(int i = 0.... normal serait votre meilleur pari.

+0

Légèrement hors sujet, mais pour certaines collections il n'est pas possible d'indexer par entier.Les dictionnaires ne sont pas indexables comme ceci et les listes liées fonctionneraient mal. J'utiliserais l'index d'itérateur plus l'index de manula et laisserai des issues de performance pour une date ultérieure. – Skizz

1

La meilleure façon absolue pour le résoudre est bien sûr d'utiliser un for() {} boucle à la place. Mais vous pouvez obtenir funky et écrire une extension méthode :)

public static void ForEachWithIndex<T>(this IEnumerable<T> items, Action<T, int> render) 
{ 
    if (items == null) 
     return; 
    int i = 0; 
    items.ForEach(item => render(item, i++)); 
} 

Et aussi l'utiliser

base_rows.ForEachWithIndex((m_row, index) => { 
    Company nu = new Company(m_row, symb_rows[index]); 
}); 

Mais là encore, peut-être une boucle for fait le travail mieux;)

0

Je peut-être envisager d'utiliser la méthode IndexOf() comme ceci:

foreach(DataRow m_row in base_rows) 
    Company nu = new Company(m_row, symb_rows.IndexOf(m_row)); 

peut-être que vous devez utiliser Array.indexOf() à la place, t Il a travaillé dans VBNET2008, car je travaille actuellement avec lui, mais je ne l'ai pas testé en C#.

For Each DataRow m_row in base_rows 
    Company nu = New Company(m_row, symb_rows(Array.IndexOf(symb_rows, m_row))) 
Next 

Donc je pourrais suggérer ce qui suit en C#.

foreach (DataRow m_row in base_rows) 
    Company nu = new Company(m_row, symb_rows[Array.IndexOf(symb_rows, m_row)]); 

Sinon, vous pourriez envisager d'utiliser for (;;) à la place, parfois il vaut mieux le faire.

for(int index = 0; index < base_rows.Length && index < symb_rows.Length; ++index) 
    Company nu = new Company(base_rows[index], symb_rows[symb_rows.IndexOf(base[index])]); 

Je ne sais pas ce que vous préférez.

+0

Avec IndexOF(), vous pouvez faire la boucle O (n^2); IndexOf (je pense) va vérifier chaque élément de la liste pour trouver l'index pour vous. –

+0

@Dean J: Je ne pouvais pas être plus d'accord. Ainsi, il satisfait l'objectif de la question qui était d'obtenir un index dans une boucle foreach(). En fait, je préfère la solution intelligente de @Eric Lippert. =) Merci pour le commentaire si! –