[我从Haskell那里学习了intersperse function,并且一直在用c#寻找实现。
Intersperse采用2个参数,一个IEnumerable
一个可能的用例是在整数列表之间放置一个任意整数,例如:
// returns: {1, 0, 2, 0, 3}
(List<int>() {1, 2, 3}).Intersperse(0);
这是string.Join(...)的一般情况。
其他人错过了的东西:如果只希望在项目之间,而不是在前面或后面,则需要进行额外的检查:
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;
}
}
本着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;
}
}
}
}
这很容易写:
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;
}
}
这里是一个示例,可以更好地控制插入其他项目:
public delegate T IntersperseFunc<T>(T prev, T next, int index);
public delegate T InterspersePrevNextFunc<T>(T prev, T next);
public delegate T IntersperseIndexFunc<out T>(int index);
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, IntersperseFunc<T> elementFunc)
{
if (source == null) throw new ArgumentNullException(nameof(source));
using (var enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
var index = 0;
var prev = enumerator.Current;
yield return prev;
while (enumerator.MoveNext())
{
var next = enumerator.Current;
yield return elementFunc(prev, next, index++);
yield return next;
prev = next;
}
}
}
}
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, InterspersePrevNextFunc<T> elementFunc)
=> Intersperse(source, (prev, next, index) => elementFunc(prev, next));
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, IntersperseIndexFunc<T> elementFunc)
=> Intersperse(source, (prev, next, index) => elementFunc(index));
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, Func<T> elementFunc)
=> Intersperse(source, (prev, next, index) => elementFunc());
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
=> Intersperse(source, (prev, next, index) => element);
[如果您想知道如何实现它,我会这样做:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> collection, T value)
{
foreach(T item in collection)
{
yield return item;
yield return value;
}
yield break;
}