Я обнаружил, что этот пост ищет то же самое, но был очень недоволен ответами (большинство похоже на объединение строк [?], И принятый ответ кажется многословным). В итоге я просто придумал другие способы сделать это.
Я предпочитаю такой способ:
public static IEnumerable<T> AfterEach <T> (this IEnumerable<T> source, T delimiter) =>
source.SelectMany((item) => Enumerable.Empty<T>().Append(item).Append(delimiter));
Или, альтернативно:
public static IEnumerable<T> AfterEach <T> (this IEnumerable<T> source, T delimiter) =>
source.SelectMany((item) => new T[] { item, delimiter });
Они оба эквивалентны: для каждого элемента создайте новую последовательность {item, delimiter} и используйте SelectMany
, чтобы объединить все вместе.
Другой подход, который не является однострочным, но может быть более легким для чтения и очень прост:
public static IEnumerable<T> AfterEach <T> (this IEnumerable<T> source, T delimiter) {
foreach (T item in source) {
yield return item;
yield return delimiter;
}
}
Если вам не нужен дополнительный разделитель в конце, подход аналогичен, за исключением того, что вы объединяете последовательности {delimiter, item}, а затем Skip
дополнительный разделитель в начале ( это более эффективно, чем пропуск одного в конце).
public static IEnumerable<T> Delimit <T> (this IEnumerable<T> source, T delimiter) =>
source.SelectMany((item) => Enumerable.Empty<T>().Append(delimiter).Append(item)).Skip(1);
public static IEnumerable<T> Delimit <T> (this IEnumerable<T> source, T delimiter) =>
source.SelectMany((item) => new T[] { delimiter, item }).Skip(1);
Подход доходности будет таким (опять же, два похожих варианта, просто зависит от того, как вы себя чувствуете):
public static IEnumerable<T> Delimit <T> (this IEnumerable<T> source, T delimiter) {
foreach (T item in source.Take(1)) // protects agains empty source
yield return item;
foreach (T item in source.Skip(1)) {
yield return delimiter;
yield return item;
}
}
public static IEnumerable<T> Delimit <T> (this IEnumerable<T> source, T delimiter) {
static IEnumerable<U> Helper<U> (IEnumerable<U> source, U delimiter) {
foreach (U item in source) {
yield return delimiter;
yield return item;
}
}
return Helper(source, delimiter).Skip(1);
}
Здесь есть несколько исполняемых примеров и тестовый код (для Delimit
, а не AfterEach
) . Там тоже есть реализация с Aggregate
, о которой я не думал, что стоит здесь писать. Аналогичным образом он может быть адаптирован к AfterEach
.
person
Jason C
schedule
11.06.2021
IEnumerable<TableRow>
работает с методом соединения, который принимает строки, другими словами, как вы на самом деле вызываете существующий метод? Я не совсем понимаю, что вы здесь ищете. - person Lasse V. Karlsen   schedule 18.04.2010String.Join
. Просто ищу ту же функциональность - вставка разделителя между элементами массива - person abatishchev   schedule 18.04.2010