0

I am trying to find the indexes as follows.

But the following LINQ says there is no extension of FindIndex.

foreach (var distinctClassId in distinctClassIds)
{
    var indexes = classComponents.Where(x=> x.ClassId.Equals(distinctClassId)).
                  FindIndex(x => x.Id == Constants.Classes.ClassID.ToString() ||
                   x.Id == Constants.Courses.CoursesID.ToString());
}
casillas
  • 16,351
  • 19
  • 115
  • 215
  • https://stackoverflow.com/questions/2471588/how-to-get-index-using-linq – Steve Dec 17 '17 at 18:27
  • What exactly should `FindIndex` do? You know that there is a `Where` overload that gives you the index of the current item as parameter to the predicate? And a `Select` overload as well? – René Vogt Dec 17 '17 at 18:27
  • 1
    `classComponents.Where(x=> x.ClassId.Equals(distinctClassId))` returns an `IEnumerable` where as the FindIndex() method is applicable on List. Change following to `var indexes = classComponents.Where(x=> x.ClassId.Equals(distinctClassId)).ToList(). FindIndex(x => x.Id == Constants.Classes.ClassID.ToString() || x.Id == Constants.Courses.CoursesID.ToString());` – Kunal Mukherjee Dec 17 '17 at 18:28
  • To avoid confusion: you named the variable `indexes`, do you expect `FindIndex` to return _multiple_ indices? `FindIndex` only returns the index of the first item that matches the predicate... – René Vogt Dec 17 '17 at 18:32
  • @RenéVogt Yes, it could be more than one. – casillas Dec 17 '17 at 18:33
  • ok, edited my answer accordingly – René Vogt Dec 17 '17 at 18:40

1 Answers1

5

FindIndex() is an instance method of List<T>. But Where() returns an IEnumerable<T> (or maybe an IQueryable<T> depending on what classComponents is in your code).

So you need to convert that Where result to list before you can call FindIndex():

foreach (var distinctClassId in distinctClassIds)
{
    var indexes = classComponents.Where(x=> x.ClassId.Equals(distinctClassId)).ToList(). // here -> ToList()
                  FindIndex(x => x.Id == Constants.Classes.ClassID.ToString() ||
                   x.Id == Constants.Courses.CoursesID.ToString());
}

But FindIndex() only gives you the index of the first matching item. Your variable is called indexes, so you might want to find the indices of multiple matching items. This can be done by using the linq overloads that give you the index, too:

foreach (var distinctClassId in distinctClassIds)
{
    var filtered = classComponents.Where(x=> x.ClassId.Equals(distinctClassId)).ToList();

    var indexes = filtered.Select((item, index) => new {item, index})
                          .Where(x => x.item.Id == Constants.Classes.ClassID.ToString() ||
                   x.item.Id == Constants.Courses.CoursesID.ToString())
                          .Select(x => x.index);
}

This creates objects of anonymous type containing the item and its index, then checking which items match and finally returning their indices.

Note: if you actually wanted the indices in the source list (classComponents), you should combine the Where statements like that:

foreach (var distinctClassId in distinctClassIds)
{
    var indexes = classComponents.Select((item, index) => new {item, index})
                    .Where(x => x.item.ClassId.Equals(distinctClassId) &&
                                (x.item.Id == Constants.Classes.ClassID.ToString() ||
                                 x.item.Id == Constants.Courses.CoursesID.ToString()))
                    .Select(x => x.index);
}
René Vogt
  • 43,056
  • 14
  • 77
  • 99