Метод расширения для Enumerable.Intersperse? - PullRequest
9 голосов
/ 15 апреля 2009

Я изучил вкрапленную функцию от Haskell и искал реализацию в c #.

Intersperse принимает 2 аргумента, источник IEnumerable и элемент T. Он возвращает IEnumerable с элементом, вставленным между каждым элементом источника.

Один из возможных вариантов использования - поместить произвольное целое число в список целых чисел, например:

// returns: {1, 0, 2, 0, 3}
(List<int>() {1, 2, 3}).Intersperse(0);

Это общий случай string.Join (...).

Ответы [ 4 ]

13 голосов
/ 15 апреля 2009

Что-то, что другие пропустили: если вы хотите, чтобы это было только между предметами, а не спереди или сзади, вам нужно сделать дополнительную проверку:

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;
    }
}
5 голосов
/ 15 апреля 2009

Я закодировал ленивое решение в духе решений 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;
            }
        }
    }
}
2 голосов
/ 15 апреля 2009

Было бы довольно легко написать:

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;
    }
}
0 голосов
/ 15 апреля 2009

Если вам интересно, как это реализовать, я бы сделал так:

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;
}
...