In this post, Khalid Abuhakmeh explores how to create an ‘intersperse’ extension method for IEnumerable in C#, inspired by a JavaScript utility. The article includes code samples, expected outputs, and a detailed explanation of the implementation.

Intersperse Values for Enumerable Collections in C#

Author: Khalid Abuhakmeh

Intersperse Values for Enumerable Collections

Photo by Super Snapper

Introduction

JavaScript comes equipped with a relatively small standard library compared to the .NET Base Class Library (BCL). While the JavaScript community has produced several attempts to provide a more standard set of utilities (see npmjs.com standard library search), many .NET developers are used to a broad and mature set of built-ins.

One such utility from the JavaScript ecosystem is intersperse, which inserts a separator element between the items of a list. Inspired by this, this post demonstrates how to create an intersperse extension method for IEnumerable collections in C#.

Intersperse Implementation in C#

Let’s look at a few practical examples and their expected output before diving into the code implementation.

Usage Examples

var hello = new string("Hello".Intersperse('-').ToArray());
var one = new string("1".Intersperse('x').ToArray());
var @null = ((IEnumerable<object>)null!).Intersperse(',').ToArray();
var array = new[] { 1, 2, 3 }.Intersperse(42).ToArray();
var menu = new [] {"Home", "About", "Privacy" }
    .Intersperse(" > ")
    .Aggregate((a, b) => $"{a}{b}");

Console.WriteLine($"'{hello}' interspersed with '-' is {hello}");
Console.WriteLine($"1 interspersed is {one}");
Console.WriteLine($"null interspersed is {@null}");
Console.WriteLine($"array interspersed is {string.Join(", ", array)}");
Console.WriteLine($"The menu is {menu}");

Expected Output

'H-e-l-l-o' interspersed with '-' is H-e-l-l-o
1 interspersed is 1
null interspersed is System.Object[]
array interspersed is 1, 42, 2, 42, 3
The menu is Home > About > Privacy

Implementation

Below is the C# implementation for the Intersperse extension method. This method is generic and can be applied to any IEnumerable<T>. By using the yield keyword, the implementation is both efficient and avoids unnecessary iterations.

public static class EnumerableExtensions
{
    public static IEnumerable<T> Intersperse<T>(this IEnumerable<T>? source, T delimiter)
    {
        if (source is null)
            yield break;

        using var enumerator = source.GetEnumerator();
        var hasFirstElement = enumerator.MoveNext();

        if (hasFirstElement == false)
            yield break;

        yield return enumerator.Current;

        while (enumerator.MoveNext())
        {
            yield return delimiter;
            yield return enumerator.Current;
        }
    }
}

Notes and Rationale

  • The method checks if the source is null and breaks early if so.
  • It uses an explicit enumerator to detect the first element and ensures correct placement of separator values.
  • The use of yield keeps enumeration lazy and minimizes memory overhead.
  • While constructs like Zip could also achieve a similar result, this approach is simpler and more straightforward for the purpose.

Conclusion

By borrowing a useful concept from JavaScript’s ecosystem, .NET developers can enhance the flexibility of collection manipulation in C#. The Intersperse extension method provides a concise and reusable way to insert delimiters in collections, following idiomatic .NET patterns.

Thank you for reading this quick blog post. As always, cheers!


Khalid Abuhakmeh's Picture

About Khalid Abuhakmeh

Khalid is a developer advocate at JetBrains focusing on .NET technologies and tooling.

This post appeared first on “Khalid Abuhakmeh’s Blog”. Read the entire article here