Search code examples
.netenumerationenumerator

.net enumeration first and last


is there a way in .NET (or some sort of standard extension methods) to ask questions of an enumeration?

For example is the current item the first or last item in the enumeration:

string s = "";

foreach (var person in PeopleListEnumerator) {

  if (PeopleListEnumerator.IsFirstItem) s += "[";

  s += person.ToString();

  if (!PeopleListEnumerator.IsLastItem) s += ",";
  else s += "]";
}

Solution

  • Just for the sake of fun, a solution to the general problem that doesn't require eager evaluation and has a single local variable (except the enumerator):

    static class TaggedEnumerableExtensions
    {
        public class TaggedItem<T>
        {
            public TaggedItem(T value, bool isFirst, bool isLast)
            {
                IsFirst = isFirst;
                IsLast = isLast;
                Value = value;
            }
            public T Value { get; private set; }
            public bool IsFirst { get; private set; }
            public bool IsLast { get; private set; }
        }
        public static IEnumerable<TaggedItem<T>> ToTaggedEnumerable<T>(this IEnumerable<T> e)
        {
            using (var enumerator = e.GetEnumerator()) {
                if (!enumerator.MoveNext())
                    yield break;
                var current = enumerator.Current;
                if (!enumerator.MoveNext()) {
                    yield return new TaggedItem<T>(current, true, true);
                    yield break;
                } else {
                    yield return new TaggedItem<T>(current, true, false);
                }
    
                for (;;) {
                    current = enumerator.Current;
                    if (!enumerator.MoveNext()) {
                        yield return new TaggedItem<T>(current, false, true);
                        yield break;
                    }
                    yield return new TaggedItem<T>(current, false, false);
                }
            }
        }
    }
    

    Test:

    class Program
    {
        static void Main(string[] args)
        {
            foreach (var item in Enumerable.Range(0, 10).ToTaggedEnumerable()) {
                Console.WriteLine("{0} {1} {2}", item.IsFirst, item.IsLast, item.Value);
            }
        }
    }