var item = list.Where(t => somecondition);
I would love to be able to find out the index of the element that was returned, in fact, in my case a
If you really just need the first index then count the ones that don't match:
var index = list.TakeWhile(t => !someCondition).Count()
Sure, it's pretty easy:
var index = list.Select((value, index) => new { value, index = index + 1 })
.Where(pair => SomeCondition(pair.value))
.Select(pair => pair.index)
.FirstOrDefault() - 1;
That will return the index if it finds anything matching, or -1 otherwise. The +1 and -1 is to get the behaviour for the case where there are no matches. If you knew that there would always be a match, it would be simpler:
var index = list.Select((value, index) => new { value, index })
.Where(pair => SomeCondition(pair.value))
.Select(pair => pair.index)
.FirstOrDefault();
If you're happy to get the rest of the list from that point onwards, SkipWhile
is definitely your friend, as mentioned by Chris. If want the rest of the list and the original index, that's easy too:
var query = list.Select((value, index) => new { value, index })
.SkipWhile(pair => !SomeCondition(pair.value))
That will give you a sequence of { value, index }
pairs from the first value matching SomeCondition
.
In reference to Jon Skeet's answer, you can use DefaultIfEmpty() before calling FirstOrDefault without adding and subtracting from the index.
var index = list.Select((value, index) => new { value, index })
.Where(pair => SomeCondition(pair.value))
.Select(pair => pair.index).DefaultIfEmpty(-1)
.FirstOrDefault();
Ofcourse its possible using IEnumerable...
public static class EnumerableExtension
{
public static int FirstIndexMatch<TItem>(this IEnumerable<TItem> items, Func<TItem,bool> matchCondition)
{
var index = 0;
foreach (var item in items)
{
if(matchCondition.Invoke(item))
{
return index;
}
index++;
}
return -1;
}
}
You can project the list items with their indexes first:
var item = list.Select((item, index) => new { Item = item, Index = index })
.Where(pair => SomeCondition(pair.Item))
.Select(result => result.Index);
If you know you have a list as opposed to something like an IEnumerbale or an IQueryable this might be nice ...
public static int IndexOf<T>(this IList<T> source, Func<T, bool> condition)
{
for (int i = 0; i < source.Count; i++)
if (condition(source[i]))
return i;
return -1;
}