Since a given string
like "Something" has spaces between the letters, for example "A l g u m a C o i s a"; how do I do this in C #?
Since a given string
like "Something" has spaces between the letters, for example "A l g u m a C o i s a"; how do I do this in C #?
The two current answers are in trouble and do not produce the expected result, at least not in all situations and according to the example shown in the question. If one of these answers is right then the question is wrong.
You should avoid problems with extra spaces placed. If you do not need to take care of the blanks, you can simplify the code (if the AP does say it, I can do it for a simpler version), but it's still much better to make the efficient form that is the main reason I posted it. I find bad options that teach you to do inefficiently (at least you should have an alert)
In addition there is inefficiency in both of them because it generates various string allocations which is going to generate a lot of pressure on the garbage collector , which matters a lot in strings which are considered slow when compared to number manipulations and are often used in loops which makes a huge difference in large volumes. You should use StringBuilder
.
So it seems more correct to me:
using static System.Console;
using System.Text;
public class Program {
public static void Main() {
var frase = " Alguma coisa ";
var espacado = new StringBuilder(frase.Length * 2 - 1);
var i = 0;
for (; i < frase.Length && frase[i] == ' '; i++);
espacado.Append(char.ToUpper(frase[i]));
for (i++; i < frase.Length; i++) {
if (frase[i] != ' ') {
espacado.Append(' ');
espacado.Append((i == 0 || frase[i - 1] == ' ') ? char.ToUpper(frase[i]) : char.ToLower(frase[i]));
}
}
WriteLine("|" + espacado + "|");
}
}
I do not really like flag , it's almost always gambiarra or lazy to find the correct way, or even language failure to express it, but in this case I think it simplifies the code: p>
using static System.Console;
using System.Text;
public class Program {
public static void Main() {
var frase = " Alguma coisa ";
var espacado = new StringBuilder(frase.Length * 2 - 1);
var primeiro = true;
for (var i = 0; i < frase.Length; i++) {
if (frase[i] == ' ') continue;
if (!primeiro) {
espacado.Append(' ');
}
primeiro = false;
espacado.Append((i == 0 || frase[i - 1] == ' ') ? char.ToUpper(frase[i]) : char.ToLower(frase[i]));
}
WriteLine("|" + espacado + "|");
}
}
See running on .NET Fiddle . And in Coding Ground . Also I put GitHub for future reference (and second form ).
In Linq there is the Select that allows you to project each element of a sequence. Remember that a string is nothing more than a string of characters.
See an example:
var str = "Alguma coisa";
var r = string.Concat(str.Select((s) => " " + s.ToString()));
Write(r);
Output:
A l g u m a c o i s a
It looks for elements of string
, what I did was concatenate with a whitespace " "
with the current element and how Select
method returns an enumerable we use Concat to concatenate all in a string
only.
See working at .NET Fiddle .
It was my fault that I did not realize that I had to keep the first letters of each word in capitals. Therefore, I created a new version correcting this bug and with some modifications.
See the code:
using static System.Console;
using System.Linq;
using System.Globalization;
using System.Text.RegularExpressions;
public class Program {
public static void Main() {
var str = " Alguma coisa outrA i i coIsA ";
var resultado = Espacar(RemoverTodosEspacos(Capitalizar(str, false, "pt-BR")));
Write($"|{resultado}|");
}
private static string Capitalizar(string texto, bool acronimo, string cultura) {
if (string.IsNullOrWhiteSpace(texto) || string.IsNullOrWhiteSpace(cultura)) {
return null;
}
TextInfo info = new CultureInfo(cultura, false).TextInfo;
if (acronimo) {
return info.ToTitleCase(texto);
}
return info.ToTitleCase(texto.ToLower());
}
private static string Espacar(string texto) {
if (string.IsNullOrWhiteSpace(texto)) {
return null;
}
return string.Concat(texto.Select((s, i) => " " + s.ToString())).TrimStart();
}
private static string RemoverTodosEspacos(string texto) {
if (string.IsNullOrWhiteSpace(texto)) {
return null;
}
return Regex.Replace(texto, @"\s+", "");
}
}
Output
| | | | | | | | | | | | | | | | | | |
The first thing you have to do is a capitalization in the string
to ensure that the first letters are uppercase. The method that does this is the ToTitleCase of class TextInfo
, and to consider using acronyms and I created the Capitalizar()
method that allows you to define which culture will be, or ignore the acronyms.
I assumed that the AP only wants a space between letters or characters, so I created a RemoverTodosEspacos()
method to remove all whitespace from the string and the TABs it contains in string
, and this method uses a regular expression .
And finally I created the Espacar()
method that is the same approach as above, except that it removes the space at the beginning of string
and checks if the string is valid.
See the new code working at .NET Fiddle .
The above approach may not be as performative as the Maniero approach.
StringBuilder
is faster and you can compare here and read more here . Of course if performance is the priority due to the volume of data and the amount of changes that will occur in string
I strongly recommend you adopt Maniero's approach.
I have not done all the testing in the code I've created and it needs improvements, even in terms of performance or possible anomalies that may occur. So, I suggest you improve it and dig deeper into it.
Sources:
Make a foreach
that will read each position of this string
, example:
using System;
public class Program
{
public static void Main()
{
string frase = "Alguma coisa".Replace(" ","");
string result = "";
foreach(var f in frase) {
if (!string.IsNullOrEmpty(result)) result += " ";
result += f;
}
Console.WriteLine(result);
}
}
Each item read from this string
is a char
, so you can mount a new string
with spaces.