Home > front end >  How to distinguish between a found 0 and default(int) when using methods like FindLast?
How to distinguish between a found 0 and default(int) when using methods like FindLast?

Time:12-13

I have a list of integers and I need to find the last occurrence that matches a predicate. To use a very simple example:

var myList = new List<int> { 1, 5, 6, 20, 18, 2, 3, 0, 4 };
var lastMatch = myList.FindLast(e => e == 0 || e == 2);

This seems like the perfect usecase for FindLast. Problem is that this method returns default(T) if nothing was found, which in the case of integers, is actually a valid value 0. So the question is, if this method returns 0, how can I know if it found something or not? Is there a better method for this case with ints?

CodePudding user response:

Use FindLastIndex instead. If the index is negative no match was found. If it isn't negative: that's the index you want, so: use the indexer with that index.

CodePudding user response:

As an alternative to @MarcGravell answer: Instead of the List FindLast method, you could use the Linq Last extension method overload that takes a predicate as an argument. It will throw an exception if no match is found.

See Last documentation

CodePudding user response:

In general case when we have IEnumerable<T> with arbitrary T (we can't play trick with int? now) we can implement an extension method:

  public static partial class EnumerableExtensions {
    public static int LastIndex<T>(this IEnumerable<T> source, 
                                        Predicate<T> predicate) {
      if (source is null)
        throw new ArgumentNullException(nameof(source));
      if (predicate is null)
        throw new ArgumentNullException(nameof(predicate));
 
      int result = -1;
      int index = -1;

      foreach (T item in source) {
        index  = 1;

        if (predicate(item))
          result = index;
      }

      return result;
    }
  }

And then

var lastMatch = myList.LastIndex(e => e == 0 || e == 2);
  • Related