#c# #linq
#c# #linq
Вопрос:
У меня есть строка, подобная
"tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33"
я хочу добавить разрыв строки через 3 запятые каждый
"tom: 1, john: 3, timmy: 5, </br> cid: 8, ad: 88, hid: 99, </br> mn: 33"
Комментарии:
1. Нет домашней работы пожалуйста, дайте нам знать, что вы пробовали до сих пор.
Ответ №1:
Я считаю for
, что цикл был бы самым простым и понятным решением, но интересно сделать это с помощью LINQ:
string input = "tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33";
char delimiter = ',';
var allParts = input.Split(delimiter);
string result = allParts.Select((item, index) => (index != 0 amp;amp; (index 1) % 3 == 0)
? item delimiter " </br>"
: index != allParts.Count() - 1 ? item delimiter : item)
.Aggregate((i, j) => i j);
// result (without a comma after the last item)
// "tom: 1, john: 3, timmy: 5, </br> cid: 8, ad: 88, hid: 99, </br> mn: 33"
Ответ №2:
string line ="tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33";
Regex regex = new Regex(@"(w ?:s d ,s){3}");
string result = regex.Replace(line, "$amp;<br /> ");
Ответ №3:
Используйте следующую часть кода, она будет работать нормально.
string input = "tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33";
string[] parts = input.Split(',');
StringBuilder result = new StringBuilder();
int i = 1;
while(i <= parts.Length)
{
result.Append(parts[i-1] ",");
if (i % 3 == 0)
{
result.Append("<br />");
}
i ;
}
Редактировать:
result = result.Remove(result.ToString().LastIndexOf(','), 1);
MessageBox.Show(result.ToString());
Комментарии:
1. Будет ли после последнего элемента
mn: 33
стоять запятая,
?
Ответ №4:
Лучшее, что я могу сделать с помощью решения LINQ:
var count = 0;
input.Aggregate(
new StringBuilder(),
(sb, ch) =>
{
sb.Append(ch);
if (ch == ',' amp;amp; count % 3 == 0) sb.Append(" </br>");
return sb;
}).ToString();
Ответ №5:
string splitter = ", ";
string newLine = "<br/>";
int splitAfter = 3;
string s = "tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33";
string x =
s.Split(new[]{splitter}, StringSplitOptions.None) // Split
// Make each string entry into a Tuple containing the string itself
// and an integer key declaring into which group it falls
.Select((v, i) =>
new Tuple<int, string>((int) Math.Floor((double) i/splitAfter), v))
// Group by the key created in the line above
.GroupBy(kvp => kvp.Item1)
// Since the key is not needed any more select only the string value
.Select(g => g.Select(kvp => kvp.Item2)
// Join the groups
// (in your example each group is a collection of 3 elements)
.Aggregate((a, b) => a splitter b))
// Join all the groups and add a new line in between
.Aggregate((a, b) => a splitter newLine b);
Это делается с помощью «одной строки» LINQ. Хотя я не совсем уверен, действительно ли это желательно, учитывая, что другому разработчику, вероятно, довольно сложно понять, что здесь происходит с первого взгляда (особенно если у вас нет большого опыта работы с LINQ и особенно с его функцией GroupBy).
Комментарии:
1. Похоже, у вас опечатка в
spliterAfter
переменной, поскольку она использовалась в запросе LINQ assplitAfter
, также я обработал ваш запрос и получил"tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33"
x
переменную, выглядит так же, как входная строка, вы проверили запрос?2. Ах да, конечно, это должно быть «splitAfter». Спасибо, что дали мне знать! И да, разделитель был неправильным (разделение на » ,» не дает никакого результата, потому что в строке нет «,» разделитель должен быть «, «).
Ответ №6:
В качестве другого варианта (хотя for
циклический подход будет более производительным, мне нравится, насколько он короток),
предполагая метод расширения, подобный этому:
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkSize)
{
return source.Where((x,i) => i % chunkSize == 0).Select((x,i) => source.Skip(i * chunkSize).Take(chunkSize));
}
Который разбивает an IEnumerable<T>
на an IEnumerable<IEnumerable<T>>
, вы могли бы использовать следующее:
var s = "tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33";
var result = string.Join(", </br>", s.Split(',').Split(3).Select(x => string.Join(",", x)));
Ответ №7:
исходя из моих очень ограниченных знаний в области программирования, я бы использовал int для подсчета количества написанных имен. (int nameCount = 0). Каждый раз, когда я писал имя, я увеличивал счетчик, если он был меньше 3, иначе я бы поставил разрыв строки.
Ответ №8:
string [] parts = yourString.Split(',');
StringBuilder result = new StringBuilder();
for(int i = 0; i < parts.Length; i )
{
result.Append(parts[i]);
if(i % 3 == 0)
{
result.Append("<br />");
}
}
Комментарии:
1. ваш код не выдаст желаемый результат, пожалуйста, проверьте один раз.
2. Конечный набор результатов должен содержать символы запятой
,
3. Упс, забыл о запятых. ответ @skk лучше моего.
4. @Bismark: Я бы не согласился с последним, потому что ваш ответ более понятен. Я бы предпочел сохранить такой простой
for
цикл, а не беспорядочный запрос LINQ для такого простого случая5. @sll, ответ skk не включает LINQ. В основном он использует почти тот же цикл, но также добавляет запятые.
Ответ №9:
Если я понял, что вы хотите, вы можете использовать indexof в foreach, а затем сделать что-то подобное:
strTarget.Вставить(strTarget.indexOf(третья запятая), «»);
Я думаю, вы можете создать некоторую логику с этим:
http://msdn.microsoft.com/en-us/library/k8b1470s.aspx
Ademar
Ответ №10:
Попробуйте это..
string[] split = textBox1.Text.Split(',');
int count =0;
for (int i = 0; i < split.Length; i )
{
count =1;
if (i < split.Length - 1)
{
textBox2.Text = split.GetValue(i) ",";
}
else
{
textBox2.Text = split.GetValue(i);
}
if (count == 3)
{
count = 0;
textBox2.Text = " </br> ";
}
}
Ответ №11:
Это даст вам требуемый результат:
string combinedValues = "tom: 1, john: 3, timmy: 5, cid: 8, ad: 88, hid: 99, mn: 33";
string[] separatedValues = combinedValues.Split(',');
for (int i = 3; i < separatedValues.Count(); i = i 3)
{
separatedValues[i] = @"<br />" separatedValues[i];
}
StringBuilder sb = new StringBuilder();
foreach (string value in separatedValues)
{
sb.Append(value);
sb.Append(@",");
}
string combinedValuesWithBreak = sb.ToString();
Комментарии:
1. Будет ли за последним элементом
mn: 33
следовать символ запятой,
?