Search code examples
c#genericsienumerablegeneric-collections

Extending IEnumerable: How do I return the last not string.empty element?


I want to create an extension method of class IEnumerable and create a method that retrieves the last item in the collection that is not string.empty. The collection will be always an array and the returned value a string.

I consider a null value an empty string.

I don't know how to do this in a generics way. I wonder if I should make it a generic method since the type will be an array of string.

I will call this function like this:

 string s = myArray.LastNotEmpty<???>();

How can I face this?

static class Enumerable
{
    public static TSource LastNotEmpty<TSource>(this IEnumerable<TSource> source)
    {

    }
}

Solution

  • static class MyEnumerable
    {
        public static TSource LastNotEmpty<TSource>(this IEnumerable<TSource> source) where TSource:String
        {
            return source.LastOrDefault(x=>!string.isNullOrEmpty(x));
        }
    }
    

    or more specific

    static class MyEnumerable
    {
        public static string LastNotEmpty(this IEnumerable<string> source) 
        {
            return source.LastOrDefault(x=>!string.isNullOrEmpty(x));
        }
    }
    

    As stated in other answers, Enumerable already exists in the System.Linq namespace so the static class has been named differently here.

    You then just make sure that your calling code has a using for the namespace of this class and then just use

    string s = myArray.LastNotEmpty();
    

    s will equal null if there are no occurrences.

    The above calling method could be used by either implementation of LastNotEmpty as the GenericType arugments could be worked out by the compiler.

    The updates below this line are not needed to answer the question they are just provided as alternative solutions for a more generic approach

    UPDATE - Just to please Recursive who wanted a fully generic solution. The OP has already stated that the collection will always be strings but...

    static class MyEnumerable {
      public static string LastNotEmpty<TSource>(this IEnumerable<TSource> source) {
        if (source==null) return null;  // Deals with null collection
        return source.OfType<string>().LastOrDefault(x=>!string.IsNullOrEmpty(x);
      }
    }
    

    This will first filter the collection to those of type string. The result will be null if the collection is null or if there are no results found..

    UPDATE Again - This is only to try and make Recursive feel good :)

    This version will return the first TSource that is not equal to either the empty string or null. The ReferenceEquals is used because resharper complains about comparing a possible value type with null...

    static class MyEnumerable {
      public static TSource LastNotEmpty<TSource>(this IEnumerable<TSource> source) {
        if (source==null) return null;  // Deals with null collection
        return source.LasdtOrDefault(x=>
                                        !ReferenceEquals(x,null)
                                        &&
                                        !x.Equals(String.Empty)
                                     );
      }
    }