tags:

views:

218

answers:

7
+2  Q: 

Index in a Foreach

I'm using a foreach currently, and need the index of the item.

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

Here's the code.

I'm trying to get the index of m_row inside of base_rows and use that to pass symb_rows[index_of_m_row]. Is this possible or should I just use a normal for loop?

+6  A: 

In order to know your current index in the collection (using a foreach) you must do this:

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

or use a standard for loop. The IEnumerable interface does not expose a positional index property as it is a forward-only iterator over an underlying sequence of items.

Andrew Hare
Yes, I'd just use a for loop, try to also use GetLowerBound, GetUpperBound and check to make sure each i is valid as you loop.
MindStalker
+1  A: 

You have to use a normal for-loop or create your own counter like Andrew Hare suggests to get this working. I would suggest using a for-loop.

gautema
+1  A: 

A normal for loop is the way to go if you need the index.

HTH,
Kent

Kent Boogaart
A: 

I would just use a normal loop.

You could have an int the increments every time you loop around but a normal for( int i = 0.... would be your best bet.

Simon G
Slightly off topic, but for some collections it is not possible to index by integer. Dictionaries are not indexable like this and Linked lists would perform badly. I would use the iterator plus manula integer index and leave performance issues for a later date.
Skizz
+11  A: 

The "for" loop solution is perfectly clear. As an interesting alternative solution, you could eschew the loop altogether:

var companies = baseRows
  .Select((row, index) => new Company(row, symbRows[index]))
  .ToList();
Eric Lippert
+1 Very clever :)
Andrew Hare
@Andrew: and therefore probably a bad idea. I dislike clever code. I like plain, boring, easy-to-read-and-understand code that doesn't require any cleverness. This technique might be useful in contexts where the semantics of the operation are more like a query than a transformation; I think in this particular case it is overkill and that a for loop would probably be the better solution. Really, this is for entertainment purposes only.
Eric Lippert
@Eric - I understand and completely agree. I did appreciate the entertainment though! :)
Andrew Hare
+1 @Eric Lippert: I really do appreciate your point view about the boring, plain, easy-to-read-and-understand code. Furthermore, this is humble to admit it about the cleverness. I really like what you though.
Will Marcouiller
+1  A: 

The absolute best way to solve it is of course to use a for() {} loop instead. But you can get funky and write a extension-method :)

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

And too use it

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

But then again, maybe a for-loop does the job better ;)

Kenny Eliasson
A: 

I would perhaps consider using the IndexOf() method like so:

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

Perhaps will you have to use Array.IndexOf() instead, this worked in VBNET2008, as I'm currently working with it, but I didn't test it in C#.

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

So I might suggest the following in C#.

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

Otherwise, you might consider using a for(;;) instead, sometimes it's better doing so.

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])]);

I don't know which you prefer though.

Will Marcouiller
With IndexOF(), you might make the loop O(n^2); IndexOf (I think) will check each element in the List to find out the index for you.
Dean J
@Dean J: I couldn't agree more. Thus, it satisfies the objective of the question which was to get an index within a foreach() loop. In fact, I prefer the clever solution of @Eric Lippert. =) Thanks for the comment though!
Will Marcouiller