I learned the intersperse function from Haskell, and have been looking for an implementation in c#.
Intersperse takes 2 arguments, an IEnumerable<T> source and a T element. It returns an IEnumerable with element inserted between every element of source.
One possible use-case is to put an arbitrary integer in between a list of integers, for example:
// returns: {1, 0, 2, 0, 3}
(List<int>() {1, 2, 3}).Intersperse(0);
This is a general case of string.Join(...).
Something the others have missed: if you only want it in between items, and not also in front or behind, you need to do an extra check:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
{
bool first = true;
foreach (T value in source)
{
if (!first) yield return element;
yield return value;
first = false;
}
}
or
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
{
var e = source.GetEnumerator();
bool b = e.MoveNext();
if (b) yield return e.Current;
while (e.MoveNext())
{
yield return element;
yield return e.Current;
}
}
I've coded up a solution that is lazy, in the spirit of Linq solutions! Other solutions I came up with involved traversing the entire list before returning data, and then returning the resulting list.
Some of the other answers have an if check on every iteration of the loop.
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
{
using (var enumerator = source.GetEnumerator()) {
if (enumerator.MoveNext()) {
yield return enumerator.Current;
while (enumerator.MoveNext()) {
yield return element;
yield return enumerator.Current;
}
}
}
}
It would be pretty easy to write:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T value) {
bool first = true;
foreach(T item in source) {
if(first) { first = false; }
else { yield return value; }
yield return item;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With