Search code examples
linqienumerableskip

Most elegant way to process first IEnumerable item differently


What would be the most elegant way to process the first IEnumerable item differently than others, without having to test on each iteration?

With a test on each iteration, it would look like this:

// "first item done" flag
bool firstDone = false;

// items is an IEnumerable<something>
foreach (var item in items)
{
    if (!firstDone)
    {
        // do this only once
        ProcessDifferently(item);
        firstDone = true;
        continue;
    }

    ProcessNormally(item);
}

If I do this:

ProcessDifferently(items.First());
ProcessNormally(items.Skip(1)); // this calls `items.GetEnumerator` again

it will invoke GetEnumerator twice, which I would like to avoid (for Linq-to-Sql cases, for example).

How would you do it, if you need to do several times around your code?


Solution

  • If I needed to do it in several places, I'd extract a method:

    public void Process<T>(IEnumerable<T> source,
                           Action<T> firstAction,
                           Action<T> remainderAction)
    {
        // TODO: Argument validation
        using (var iterator = source.GetEnumerator())
        {
            if (iterator.MoveNext())
            {
                firstAction(iterator.Current);
            }
            while (iterator.MoveNext())
            {
                remainderAction(iterator.Current);
            }
        }
    }
    

    Called as:

    Process(items, ProcessDifferently, ProcessNormally);
    

    There are other options too, but it would really depend on the situation.