Я знаю, что концепция String.Split была рассмотрена ранее множеством различных подходов, но меня особенно интересует решение LINQ по этому вопросу.Разделите строку на список строк N-длины, используя LINQ
Я попытался написать класс расширения для обработки split, но обе попытки имеют некоторые серьезные проблемы. Так следующее:
string s = "ABCDEFGHIJKLMNOPQRSTUVWX";
var results = s.SplitEvery(4);
Я хотел бы список как: { "ABCD", "EFGH", "IJKL", "MNOP", "QRST", "UVWX"}
Здесь мой класс расширения:
public static class Extensions
{
public static List<string> SplitEvery(this string s, int n)
{
List<string> list = new List<string>();
var Attempt1 = s.Select((c, i) => i % n== 0 ? s.Substring(i, n) : "|").Where(x => x != "|").ToList();
var Attempt2 = s.Where((c, i) => i % n== 0).Select((c, i) => s.Substring(i, n)).ToList();
return list;
}
}
Попытка 1 вставляет фиктивную строку "|" каждый раз, когда условие не выполняется, затем удаляет все экземпляры фиктивной строки для создания окончательного списка. Он работает, но создание плохих строк кажется ненужным дополнительным шагом. Кроме того, эта попытка не выполняется, если строка не делится на n.
Попытка 2 пыталась выбрать только подстроки, где индекс был делимым на N, но значение «i» в выражении Select не соответствует значению «i» в инструкции Where, поэтому я получаю результаты например: {«ABCD», «BCDE» и т. д.)
Я чувствую, что я близок к хорошему решению, но могу использовать полезный толчок в правильном направлении. Какие-либо предложения?
[Редактировать]
Я в конечном итоге происходит с комбинацией предложений, чтобы справиться с моей строковое разветвитель. Это может быть не самый быстрый, но, как новичок в LINQ, эта реализация была наиболее кратким и легким для меня.
public static List<string> SplitEvery(this string s, int size)
{
return s.Select((x, i) => i)
.Where(i => i % size == 0)
.Select(i => String.Concat(s.Skip(i).Take(size))).ToList();
}
Спасибо за все замечательные предложения.
Сторона примечания: было бы неплохо указать, каковы ваши «лучшие» критерии. То естьв этом случае это, по-видимому, «запрос, читаемый новичком пользователя LINQ, который соответствует описанию как можно ближе, предпочитает« перечислимые »методы по всем соображениям производительности». В этом Lite 'Concat' с' Take' действительно будет выглядеть как лучший подход. –
Приношу свои извинения, это справедливая оценка. Меня в основном интересовал чистый, однострочный подход, похожий на мои первоначальные попытки выше. В моем случае читаемость была для меня более важной, чем масштабируемость. Надеюсь, никто не попытается выгрузить огромный текстовый файл в мою строку. :) – MadHenchbot
(Мой комментарий выше - чистое предложение - ничего не извиниться за). Еще одна случайная нота, которую нужно отслеживать в LINQ - ваш окончательный подход повторяет последовательность несколько раз. Это нормально для строки, но не будет работать для «одноразовых» последовательностей, таких как результат SQL-запроса или «File.ReadAllLines». Существует несколько ответов (т. Е. С возвратом доходности), которые демонстрируют подходы, которые повторяют сборку один раз. –