Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEnumerable.Count() O(n)

I just stumbled upon this fragment of code, I was wondering why the Count is done during the loop.

  /// <summary>
  /// find the first index in a sequence to satisfy a condition
  /// </summary>
  /// <typeparam name="T">type of elements in source</typeparam>
  /// <param name="source">sequence of items</param>
  /// <param name="predicate">condition of item to find</param>
  /// <returns>the first index found, or -1 if not found</returns>
  public static int FindIndex<T>(this IEnumerable<T> source, Predicate<T> predicate)
  {
         for (int i = 0; i < source.Count(); i++)
         {
               if (predicate(source.ElementAt(i))) return i;
         }
         return -1; // Not found
  }

If the count can change, shouldn’t we just do it like this instead: for (int i = source.Count() - 1; i >= 0; i--)

Otherwise, I think we should calculate the count before the looping starts, instead of every time.

What would be the correct way to do this?

like image 473
bevacqua Avatar asked Dec 05 '11 17:12

bevacqua


People also ask

How do I count items in IEnumerable?

IEnumerable has not Count function or property. To get this, you can store count variable (with foreach, for example) or solve using Linq to get count.

Does IEnumerable have count?

IEnumerable doesn't have a Count method.

What is the difference between count and count () in C#?

Count() is there as an extension method from LINQ - Count is a property on List s, actual . NET collection objects. As such, Count() will almost always be slower, since it will enumerate the collection / queryable object. On a list, queue, stack etc, use Count .

How do I know if IEnumerable has an item?

enumerable. Any() is the cleanest way to check if there are any items in the list.


1 Answers

The correct way to write manual code for this would be to lose all that rubbish and simply iterate with foreach:

public static int FindIndex<T>(this IEnumerable<T> source, Predicate<T> predicate) 
{
    var index = 0;
    foreach(var item in source) {
        if(predicate(item)) {
            return index;
        }
        ++index;
    }

    return -1;
} 
like image 101
Jon Avatar answered Sep 22 '22 11:09

Jon