Я хотел довести эту проблему до сведения сообщества stackoverflow. Исходная проблема и ответы: здесь . Кстати, если вы не следили за этим раньше, вы должны попытаться прочитать блог Эрика, это чистая мудрость.
Резюме:
Напишите функцию, которая принимает ненулевое значение IEnumerable и возвращает строку со следующими характеристиками:
- Если последовательность пуста, в результате получается строка "{}".
- Если последовательность представляет собой один элемент «ABC», тогда полученная строка будет «{ABC}».
- Если последовательность представляет собой последовательность из двух элементов «ABC», «DEF», то полученная строка будет «{ABC and DEF}».
- Если последовательность содержит более двух элементов, скажем, «ABC», «DEF», «G», «H», то полученная строка будет «{ABC, DEF, G и H}». (Примечание: запятая не оксфордская!)
Как вы можете видеть, даже наш собственный Джон Скит (да, хорошо известно, что он может быть в двух местах одновременно ) опубликовал решение, но его (ИМХО) нет самый элегантный, хотя, вероятно, вы не можете побить его производительность.
Что ты думаешь? Там есть довольно хорошие варианты. Мне действительно нравится одно из решений, которое включает методы выбора и агрегирования (от Фернандо Николе). Linq очень силен и посвящает некоторое время таким вызовам, чтобы вы многому научились. Я немного изменил его, чтобы он был более производительным и понятным (используя Count и избегая Reverse):
public static string CommaQuibbling(IEnumerable<string> items)
{
int last = items.Count() - 1;
Func<int, string> getSeparator = (i) => i == 0 ? string.Empty : (i == last ? " and " : ", ");
string answer = string.Empty;
return "{" + items.Select((s, i) => new { Index = i, Value = s })
.Aggregate(answer, (s, a) => s + getSeparator(a.Index) + a.Value) + "}";
}