5

Иногда я нахожу, что мне нужно обработать список, вставив новый элемент после каждого элемента, кроме последнего. Подобно тому, как вы можете поместить запятую между каждым элементом списка строк.В функциональном манипулировании списком, что мы называем «вставляем что-то между каждым элементом»?

я пресытился кодирование особого случая за последний (или первый) пункт каждый раз, так что я захватил шаблон в расширении в 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 операции над списками, обычно называемыми в других функциональных рамках или языках?

ответ

14

Haskell: intersperse

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

+1

Интересно, это было мое предположение и для хорошего имени, но я не знал, что он уже использовался в Haskell :) –

+2

Haskell и печать одобрения Skeet, почему это практически золотой стандарт! –

+0

Да, одно из полезных имен функций Haskell (просто думая о mapM_ и т. Д .;)) – Dario

0

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

+0

Zip - это другая операция, хотя преобразование двух последовательностей в новую последовательность кортежей. –

2

Это часто называют Объединить.

+0

'Join' имеет аналогичное значение в' String', но уже имеет совсем другое значение в BCL на 'IEnumerable'. –

+0

+1 Регистрация будет знакома пользователям perl, она менее знакома функциональным пользователям, немного неудачна. Мне нравится межпространственное имя, но это заслуживающая внимания идея. – ShuggyCoUk

+0

Хотя обычно это операция, зависящая от строки, есть также String.join в Python, Ruby и, возможно, несколько других языков, так что это определенно не плохое имя для такого рода операций. – MatrixFrog

1

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

1

Он также называется interpose в Clojure.

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