Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current index from foreach loop [duplicate]

Using C# and Silverlight

How do I get the index of the current item in the list?

Code:

IEnumerable list = DataGridDetail.ItemsSource as IEnumerable;
List<string> lstFile = new List<string>();


foreach (var row in list)
{
  bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row)).IsChecked;
  if (IsChecked)
  {

    // Here I want to get the index or current row from the list                   

  }
}

How to achieve this

like image 438
Gopal Avatar asked Apr 27 '16 06:04

Gopal


People also ask

How do you get the index of the current iteration of a foreach loop?

by using automatic destructuring: foreach (var (value, i) in Model.

Does foreach make a copy of the array?

forEach() does not make a copy of the array before iterating.

How do you get the first value in foreach?

Method 1: It is the naive method inside foreach loop to find iteration. Use a counter variable and check when the counter value is zero then it is the first iteration and when the counter value is length-1 then it is the last iteration.


2 Answers

You can't, because IEnumerable doesn't have an index at all... if you are sure your enumerable has less than int.MaxValue elements (or long.MaxValue if you use a long index), you can:

  1. Don't use foreach, and use a for loop, converting your IEnumerable to a generic enumerable first:

    var genericList = list.Cast<object>();
    for(int i = 0; i < genericList.Count(); ++i)
    {
       var row = genericList.ElementAt(i);
       /* .... */
    }
    
  2. Have an external index:

    int i = 0;
    foreach(var row in list)
    {
       /* .... */
       ++i;
    }
    
  3. Get the index via Linq:

    foreach(var rowObject in list.Cast<object>().Select((r, i) => new {Row=r, Index=i}))
    {
      var row = rowObject.Row;
      var i = rowObject.Index;
      /* .... */    
    }
    

In your case, since your IEnumerable is not a generic one, I'd rather use the foreach with external index (second method)... otherwise, you may want to make the Cast<object> outside your loop to convert it to an IEnumerable<object>.

Your datatype is not clear from the question, but I'm assuming object since it's an items source (it could be DataGridRow)... you may want to check if it's directly convertible to a generic IEnumerable<object> without having to call Cast<object>(), but I'll make no such assumptions.


All this said:

The concept of an "index" is foreign to an IEnumerable. An IEnumerable can be potentially infinite. In your example, you are using the ItemsSource of a DataGrid, so more likely your IEnumerable is just a list of objects (or DataRows), with a finite (and hopefully less than int.MaxValue) number of members, but IEnumerable can represent anything that can be enumerated (and an enumeration can potentially never end).

Take this example:

public static IEnumerable InfiniteEnumerable()
{
  var rnd = new Random();
  while(true)
  {
    yield return rnd.Next();
  }
}

So if you do:

foreach(var row in InfiniteEnumerable())
{
  /* ... */
}

Your foreach will be infinite: if you used an int (or long) index, you'll eventually overflow it (and unless you use an unchecked context, it'll throw an exception if you keep adding to it: even if you used unchecked, the index would be meaningless also... at some point -when it overflows- the index will be the same for two different values).

So, while the examples given work for a typical usage, I'd rather not use an index at all if you can avoid it.

like image 163
Jcl Avatar answered Sep 30 '22 18:09

Jcl


IEnumerable list = DataGridDetail.ItemsSource as IEnumerable;
List<string> lstFile = new List<string>();

int i = 0;
foreach (var row in list)
{
bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row)).IsChecked;
if (IsChecked)
{
  MessageBox.show(i);
--Here i want to get the index or current row from the list                   

}
 ++i;
}
like image 44
tapos ghosh Avatar answered Sep 30 '22 20:09

tapos ghosh