При функциональном манипулировании списком, что мы называем “вставкой чего-либо между каждым элементом”?

StackOverflow https://stackoverflow.com/questions/1158573

Вопрос

Иногда я обнаруживаю, что мне нужно обработать список, вставляя новый элемент после каждого элемента, кроме последнего.Аналогично тому, как вы могли бы поставить запятую между каждым элементом списка строк.

Мне надоело каждый раз кодировать особый случай для последнего (или первого) элемента, поэтому я записал шаблон в расширении в стиле Linq:

public static IEnumerable<T> Separate<T>(this IEnumerable<T> source, 
                                         Func<T> separator)
{
    bool first = true;
    foreach (T item in source)
    {
        if (first)
            first = false;
        else
            yield return separator();

        yield return item;
    }
}

Например, это позволяет мне легко программно заполнить документ потока гиперссылками, но с разрывом строки между каждой из них:

para.Inlines.AddRange(_recentFiles.Select(f => f.ToHyperlink())
                                  .Separate(() => new LineBreak()));

Предполагая, что это еще не существует в System.Linq.Enumerable (что я обычно обнаруживаю сразу после написания чего-то подобного), вопрос в том, что это Separate работа со списками, обычно вызываемыми в других функциональных фреймворках или языках?

Это было полезно?

Решение

Хаскелл: intersperse

Zip обычно означает другую операцию (zip [a, b, c] [x, y, z] = [(a, x), (b, y), (c, z)])

Другие советы

Это часто называют Присоединением.

Это немного похоже на string .Join() , хотя Join не возвращает реальный список.

Это также называется interpose in Clojure.

user> (interpose "," ["a" "b" "c"])
("a" "," "b" "," "c")

Звучит как застегивание молнии (британская застежка-молния), с данными на длинной стороне и разделителем на другой :-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top