Enumerable.Intersperse的扩展方法?

Dan*_*iel 9 c# ienumerable

我从Haskell 学到了散布函数,并一直在寻找c#中的实现.

Intersperse有2个参数,一个IEnumerable <T>源和一个T元素.它返回一个IEnumerable,其中元素插入源的每个元素之间.

一种可能的用例是在整数列表之间放置一个任意整数,例如:

// returns: {1, 0, 2, 0, 3}
(List<int>() {1, 2, 3}).Intersperse(0);
Run Code Online (Sandbox Code Playgroud)

这是string.Join(...)的一般情况.

Joe*_*orn 13

其他人错过了一些东西:如果你只想在它们之间,而不是在前面或后面,你需要做一个额外的检查:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 5

我本着Linq解决方案的精神编写了一个懒惰的解决方案!我提出的其他解决方案涉及在返回数据之前遍历整个列表,然后返回结果列表.

其他一些答案在循环的每次迭代中都有if检查.

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在集合很大的情况下消除分支是很好的.顺便说一下,这是一个经典的"围栏后问题",你需要n + 1或n-1的东西.`String.Join()`是C#与这些联系最常见的方式. (2认同)