47

I have an IEnumerable object. I would like to access based on index for instance:

for(i=0; i<=Model.Products; i++)
{
      ???
}

Is this possible?

Alexander Derck
  • 13,818
  • 5
  • 54
  • 76
dcpartners
  • 5,176
  • 13
  • 50
  • 73
  • 1
    @Avram An `IEnumerator` is an entirely sensible thing to want to get the index of an item of. – Servy Jun 02 '14 at 14:33
  • @Servy IEnumerator paired with IEnumerable, need to add IEnumerable as part of the question – Avram Jun 02 '14 at 14:43
  • 4
    @Avram No, you *don't* need to. He's free to ask about whichever one he wants to ask about. He choose to ask about `IEnumerator`, which is a perfectly fine question to ask about. Just because it's not the question you'd like to answer/have answered doesn't mean you should change this question. – Servy Jun 02 '14 at 14:45

5 Answers5

159

First of all, are you sure it's really IEnumerator and not IEnumerable? I strongly suspect it's actually the latter.

Furthermore, the question is not entirely clear. Do you have an index, and you want to get an object at that index? If so, and if indeed you have an IEnumerable (not IEnumerator), you can do this:

using System.Linq;
...
var product = Model.Products.ElementAt(i);

If you want to enumerate the entire collection, but also want to have an index for each element, then V.A.'s or Nestor's answers are what you want.

Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
  • 1
    It's embarrassing that this isn't the accepted answer. Just had a problem where I was trying to write a function that needed to take either a List or an Array ("No problem! I'll just use IEnumerable<>!") - only to find indexing didn't work. ElementAt is the perfect solution... not enumerating the entire structure. (I can just imagine someone using an enumerating solution inside a loop to access each individual slot.... ugh...) – Kevin Oct 31 '19 at 18:27
29

There is no index in IEnumerator. Use

foreach(var item in Model.Products)
{
   ...item...
}

you can make your own index if you want:

int i=0;
foreach(var item in Model.Products)
{
    ... item...
    i++;
}
Nestor
  • 13,706
  • 11
  • 78
  • 119
27
var myProducts = Models.Products.ToList();
for(i=0; i< myProducts.Count ; i++)
{
      //myProducts[i];
}
Graviton
  • 81,782
  • 146
  • 424
  • 602
  • 14
    and also beaware that .ToList() is creating a new list in memory. Is that worth it (all that waste just to have an index?) – Nestor Oct 31 '09 at 12:23
  • 3
    That's pretty nasty. So if there are 10,000 products, and he needs the 5th, you tell him to load all 10k into memory first, just to discard the 9,554 he won't need? – Pavel Minaev Nov 16 '09 at 21:16
  • 1
    @Nestor: That would really depend on the situation. I don't see a reason for needing an index anyway (a counter would do), so who knows. – Ed S. Nov 16 '09 at 21:17
14
foreach(var indexedProduct in Model.Products.Select((p, i)=> new {Product = p, Index = i})
{
   ...
   ...indexedProduct.Product...
   ...indexProduct.Index ...//this is what you need.
   ...
}
V.A.
  • 141
  • 2
2

The best way to retrieve an item by index is to reference your enumerable collection with an array using Linq in this way:

using System.Linq;
...
class Model {
    IEnumerable<Product> Products;
}
...
// Somewhere else in your solution,
// assume model is an instance of the Model class
// and that Products references a concrete generic collection
// of Product such as, for example, a List<Product>.
...
var item = model.Products.ToArray()[index];
bert
  • 76
  • 5