Dividir una cadena / número cada Nth Carácter / Número?

Necesito dividir un número en partes pares, por ejemplo:
32427237 debe convertirse en 324 272 37
103092501 debe convertirse en 103 092 501

Estoy seguro de que podría hacer los próximos números, pero estoy seguro de que hay una manera más eficiente, ya que no quiero perderme los personajes de estos números, los números en sí pueden ser de cualquier longitud, así que si el número fuera 1234567890 Quiero que se divida en estas partes 123 456 789 0

He visto ejemplos en otros lenguajes como Python, etc. pero no los entiendo lo suficientemente bien como para convertirlos a C # – bucleando a través de los caracteres y luego en el tercero obteniendo el anterior y luego ese índice para obtener la sección de la cadena. hacer el trabajo, pero estoy abierto a sugerencias sobre cómo lograr esto mejor.

Si tiene que hacer eso en muchos lugares de su código, puede crear un método de extensión elegante:

static class StringExtensions { public static IEnumerable SplitInParts(this String s, Int32 partLength) { if (s == null) throw new ArgumentNullException("s"); if (partLength <= 0) throw new ArgumentException("Part length has to be positive.", "partLength"); for (var i = 0; i < s.Length; i += partLength) yield return s.Substring(i, Math.Min(partLength, s.Length - i)); } } 

Puede usarlo así:

 var parts = "32427237".SplitInParts(3); Console.WriteLine(String.Join(" ", parts)); 

La salida es 324 272 37 como se desee.

Puede usar un bucle for para insertar espacios en blanco en cada posición n-ésima:

 string input = "12345678"; StringBuilder sb = new StringBuilder(); for (int i = 0; i < input.Length; i++) { if (i % 3 == 0) sb.Append(' '); sb.Append(input[i]); } string formatted = sb.ToString(); 

Reglas LINQ:

 var input = "1234567890"; var parts = 3; var output = input.ToCharArray() .BufferWithCount(parts) .Select(c => new String(c.ToArray())); 

ACTUALIZADO:

 string input = "1234567890"; double parts = 3; int k = 0; var output = input .ToLookup(c => Math.Floor(k++ / parts)) .Select(e => new String(e.ToArray())); 

Una forma muy simple de hacer esto (no la más eficiente, pero luego no órdenes de magnitud más lenta que la más eficiente).

  public static List GetChunks(string value, int chunkSize) { List triplets = new List(); while (value.Length > chunkSize) { triplets.Add(value.Substring(0, chunkSize)); value = value.Substring(chunkSize); } if (value != "") triplets.Add(value); return triplets; } 

Aquí hay un suplente

  public static List GetChunkss(string value, int chunkSize) { List triplets = new List(); for(int i = 0; i < value.Length; i += chunkSize) if(i + chunkSize > value.Length) triplets.Add(value.Substring(i)); else triplets.Add(value.Substring(i, chunkSize)); return triplets; } 

El método de división:

 public static IEnumerable SplitInGroups(this string original, int size) { var p = 0; var l = original.Length; while (l - p > size) { yield return original.Substring(p, size); p += size; } yield return original.Substring(p); } 

Para unir de nuevo como una cadena, delimitada por espacios:

 var joined = String.Join(" ", myNumber.SplitInGroups(3).ToArray()); 

Edición: me gusta más la solución Martin Liversage 🙂

Editar 2: corrigió un error.

Editar 3: código agregado para unir la cadena de nuevo.

Esto es media década tarde pero:

 int n = 3; string originalString = "32427237"; string splitString = string.Join(string.Empty,originalString.Select((x, i) => i > 0 && i % n == 0 ? string.Format(" {0}", x) : x.ToString())); 

Haría algo como esto, aunque estoy seguro de que hay otras formas. Debería funcionar bastante bien.

 public static string Format(string number, int batchSize, string separator) { StringBuilder sb = new StringBuilder(); for (int i = 0; i <= number.Length / batchSize; i++) { if (i > 0) sb.Append(separator); int currentIndex = i * batchSize; sb.Append(number.Substring(currentIndex, Math.Min(batchSize, number.Length - currentIndex))); } return sb.ToString(); } 

Me gusta esto porque es genial, aunque no super eficiente:

 var n = 3; var split = "12345678900" .Select((c, i) => new { letter = c, group = i / n }) .GroupBy(l => l.group, l => l.letter) .Select(g => string.Join("", g)) .ToList(); 

Prueba esto:

 Regex.Split(num.toString(), "(?<=^(.{8})+)"); 

Si sabes que la longitud de toda la cuerda es exactamente divisible por el tamaño de la parte, utiliza:

 var whole = "32427237!"; var partSize = 3; var parts = Enumerable.Range(0, whole.Length / partSize) .Select(i => whole.Substring(i * partSize, partSize)); 

Pero si existe la posibilidad de que toda la cadena tenga un fragmento fraccionario al final, necesitas un poco más de sofisticación:

 var whole = "32427237"; var partSize = 3; var parts = Enumerable.Range(0, (whole.Length + partSize - 1) / partSize) .Select(i => whole.Substring(i * partSize, Math.Min(whole.Length - i * partSize, partSize))); 

En estos ejemplos, las partes serán un IEnumerable, pero puede agregar .ToArray () o .ToList () al final en caso de que desee un valor de cadena [] o de lista .

Una buena implementación que utiliza respuestas de otras preguntas de StackOverflow:

 "32427237" .AsChunks(3) .Select(vc => new String(vc)) .ToCsv(" "); // "324 272 37" "103092501" .AsChunks(3) .Select(vc => new String(vc)) .ToCsv(" "); // "103 092 501" 

AsChunks (): https://stackoverflow.com/a/22452051/538763

ToCsv (): https://stackoverflow.com/a/45891332/538763

Esto podría estar fuera de tema ya que no sé por qué deseas formatear los números de esta manera, así que ignora esta publicación si no es relevante …

Cómo se muestra un entero difiere en diferentes culturas. Debe hacerlo de una manera independiente local para que sea más fácil localizar los cambios en un momento posterior.

int.ToString toma diferentes parámetros que puede usar para formatear para diferentes culturas. El parámetro “N” le da un formato estándar para la agrupación específica de la cultura.

El formato steve x string también es un gran recurso.