-2

I have a simple question that I can't find a clean answer to when I google.

How do I iterate a foreach loop between index 40-60 and get the values for the indexes?

List<int> list1 = new List<int>();
for (int i = 0; i < 100; i++)
{
    list1.Add(i);
}
foreach (var i in list1) 
{
    //How to iterate between index: 40 to 60 ?
}
Mureinik
  • 252,575
  • 45
  • 248
  • 283
Andreas
  • 867
  • 2
  • 10
  • 20
  • 2
    Why do you want to use `foreach`? You should just use a regular `for` there and specify 40 and 60 as the start and end indices. – Herohtar Apr 09 '20 at 21:19
  • @Herohtar, I like to test if foreach is faster then the for loop as I am micro-optimizing some loops. The foreach loop is faster when iterating all elements and I like to try to put a start and end index as well. – Andreas Apr 09 '20 at 21:19
  • This might help with your optimization question: https://stackoverflow.com/questions/365615/in-net-which-loop-runs-faster-for-or-foreach (Hint: `for` is faster) – Herohtar Apr 09 '20 at 21:21
  • 2
    @Andreas `foreach` would never be faster than `for` when dealing with a collection that is indexed. It is if say you used `ElementAt` on something that had to iterated the collection to get to the position. – juharr Apr 09 '20 at 21:30
  • @juharr, yes you are right. It seems that the for loop is the one to choose if needing to iterate between 2 indexes. – Andreas Apr 09 '20 at 21:40

4 Answers4

3

The easiest approach would be to use a regular for loop:

for (int i = 40; i < 60; ++i)
{
    int value = list1[i];
    // Do something with the value
}

Note - if you want to get the value for index 60 too (i.e., the range is inclusive), you should use the <= operator instead of <.

Mureinik
  • 252,575
  • 45
  • 248
  • 283
1

Foreach loop doesn't use an index for traversing an array or collection. They take advantage of the enumerator in an IEnumerable. This answer here has a great explanation of that.

If you want you can add an int before the foreach loop and increment within the loop, but that's all you can do. I would advise that you filter your list1 beforehand and then use it in the foreach loop.

KingOfArrows
  • 513
  • 1
  • 7
1

If you really want to use a foreach then you need to write this

List<int> list1 = new List<int>();
foreach(int i in Enumerable.Range(40, 20))
{
    list1.Add(i);
}

But, lacking better info on your request to use foreach, then I agree to use a standard for-loop

Steve
  • 203,265
  • 19
  • 210
  • 265
  • 1
    That Enumerable.Range was actually almost 3 times slower than the `for-loop` So perheps the for loop is the one to choose after all if one needs to iterate between 2 indexes. – Andreas Apr 09 '20 at 21:38
0

Aside from other more appropriate answers (e.g. just use a for loop), here's a solution that uses the .Where() overload that provides the index of the element as a parameter to the predicate:

foreach (var i in list1.Where((x, index) => index >= 40 && index <= 60))
{
    //How to iterate between index: 40 to 60 ?
}
devNull
  • 2,753
  • 1
  • 10
  • 10
  • 2
    This definitely will be much slower than a `for` loop, which is what the OP is actually after based on his comments. – Herohtar Apr 09 '20 at 21:36
  • According to the [source](https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,e2d8014ab698cbfc,references), this will enumerate all content of the list. Definitely far slower than even a naive .Skip(40).Take(20) – Martheen Apr 09 '20 at 21:41
  • Yes you are right. I noticed almost 10 times slower with this approach actually. – Andreas Apr 09 '20 at 21:42