using System.Collections.Generic;
public static class Program {
public static IEnumerable<T> Delimit1a <T> (this IEnumerable<T> source, T delimiter) =>
source.SelectMany((item) => Enumerable.Empty<T>().Append(delimiter).Append(item)).Skip(1);
public static IEnumerable<T> Delimit1b <T> (this IEnumerable<T> source, T delimiter) =>
source.SelectMany((item) => new T[] { delimiter, item }).Skip(1);
public static IEnumerable<T> Delimit2a <T> (this IEnumerable<T> source, T delimiter) =>
source.Aggregate(Enumerable.Empty<T>(), (delimited, item) => delimited.Append(delimiter).Append(item)).Skip(1);
public static IEnumerable<T> Delimit2b <T> (this IEnumerable<T> source, T delimiter) =>
source.Aggregate(null as IEnumerable<T>, (delimited, item) => (delimited?.Append(delimiter) ?? Enumerable.Empty<T>()).Append(item)) ?? Enumerable.Empty<T>();
public static IEnumerable<T> Delimit3a <T> (this IEnumerable<T> source, T delimiter) {
foreach (T item in source.Take(1))
foreach (T item in source.Skip(1)) {
public static IEnumerable<T> Delimit3b <T> (this IEnumerable<T> source, T delimiter) {
static IEnumerable<U> Helper<U> (IEnumerable<U> source, U delimiter) {
foreach (U item in source) {
return Helper(source, delimiter).Skip(1);
public static void Main () {
foreach (int count in new int[] { 11, 2, 1, 0 }) {
p( Enumerable.Range(10, count).Delimit1a(-1) );
p( Enumerable.Range(10, count).Delimit1b(-1) );
p( Enumerable.Range(10, count).Delimit2a(-1) );
p( Enumerable.Range(10, count).Delimit2b(-1) );
p( Enumerable.Range(10, count).Delimit3a(-1) );
p( Enumerable.Range(10, count).Delimit3b(-1) );
static void p <T> (IEnumerable<T> e) =>
Console.WriteLine($"[ {string.Join(", ", e)} ]");