2010-11-09 17 views
45

I necesidad de dividir un número en partes, incluso por ejemplo:
32427237 necesita convertirse en 324 272 103 092 501 37
necesidades para convertirse en 103 092 501Dividir una cadena/número cada enésimo carácter/número?

estoy seguro de que pude sólo por-lado los 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, me gustaría dividirlo en estas partes 123 456 789 0

He visto ejemplos en otros idiomas como Python, etc. pero no los entiendo lo suficientemente bien como para convertirlos a C# - bucle 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 puede hacer el trabajo, pero estoy abierto a sugerencias sobre cómo lograr esto mejor.

+1

¿Desea dividir la cadena en tres cadenas separadas, o ¿quieres insertar espacios? –

+2

http://stackoverflow.com/questions/3760152/split-string-to-equal-length-substrings-in-java .Todas las respuestas están en java, pero puede transferirlas fácilmente a C#. – Emil

+0

Serían tres cadenas separadas – RoguePlanetoid

Respuesta

90

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

static class StringExtensions { 

    public static IEnumerable<String> 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)); 
    } 

} 

A continuación, puede utilizar de esta manera:

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

La salida es 324 272 37 lo deseas.

+1

+1 única solución (todavía) que utiliza una 'n' como una parámetro. – st0le

+2

método de extensión IMHO aquí es overkill. El "número" en cuestión que se dividirá es '' un tipo específico de cosa, p. un número de orden Si puede restringir el método de extensión para que solo se aplique a Números de pedido, entonces bien. Tal como está, puedes aplicarlo a cualquier entidad que esté almacenada en una cadena, esto rompe la encapsulación. –

+0

De hecho, pensé en un método que permitiría que una cuerda se divida en cualquier parte del tamaño - ¡probaré esto! – RoguePlanetoid

3

Una muy forma sencilla de hacer esto (no el más eficiente, pero no órdenes de magnitud más lento que el más eficiente).

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

Heres un suplente

public static List<string> GetChunkss(string value, int chunkSize) 
    { 
     List<string> triplets = new List<string>(); 
     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; 
    } 
+0

Una versión 'n' genérica sería mejor. – st0le

+0

@ st0le: no ciencia de cohetes para trabajar en variable chunksize :) –

7

Se puede usar un sencillo bucle para insertar espacios en blanco en cada posición ené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(); 
+0

Esto es similar a lo que originalmente iba a crear, pero estaba interesado en ver otras alternativas – RoguePlanetoid

0

Esto podría ser fuera de tema, ya que no sé por qué desea dar formato a los números de esta manera, así que por favor ignore este mensaje si no es relevante ...

Cómo se muestra un entero difiere entre 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 proporciona un formato estándar para agrupaciones específicas de cultivo.

steve x string formatting es también un gran recurso.

+0

Son solo números. No estoy obedeciendo ningún tipo de formato de número normal, por eso mencioné cadena/número, ya que los voy a usar para algo que requiere este formato en particular. – RoguePlanetoid

3

El método de división:

public static IEnumerable<string> 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 la espalda como una cadena, delimitada por espacios:

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

Editar: Me gusta Martin solución Liversage mejor :)

Edición 2: Se corrigió un error.

Edición 3: Se agregó un código para unir la cadena.

2

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(); 
} 
1

me gusta esta causa su fresco, aunque no muy 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(); 
+0

Soy parcial de Linq, pero la eficiencia es un requisito; gracias por el ejemplo aunque – RoguePlanetoid

5

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())); 
+1

'System.Linq.EnumerableEx.BufferWithCount' es parte de Reactive Extensions para .NET (Rx): http://msdn.microsoft.com /en-us/devlabs/ee794896.aspx. Deberá descargar e instalar esto para que el código se ejecute. –

+0

Gracias, no había visto BufferWithCount antes, ahora sé por qué, tengo Rx instalado, así que puede ser útil para otra cosa. – RoguePlanetoid

0

intente lo siguiente:

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

Si sabe que la longitud de toda la cadena es exactamente divisible por el tamaño de la pieza, a continuación, utilizar:

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

Pero si hay una posibilidad de toda la cadena puede tener una parte fraccionaria al final, lo que necesita 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 quiera una cadena [] o Lista <cadena> valor.

+0

Debe agregar su propia respuesta a una pregunta ya respondida si cree que está agregando valor a la respuesta aceptada. No parece que este sea el caso. –

+0

No entiendo. Esta fue la décima respuesta a esta pregunta, y solo la tercera que se puede hacer en una sola declaración (usando Linq), y creo que es la más eficiente de esas 3. Hice mal al agregar esta respuesta diferente y posiblemente mejor ? –

2

Esta es la mitad de una 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())); 
+2

Nunca es tarde para una respuesta, me pregunto si hay una solución LINQ y ¡aquí está! – RoguePlanetoid

Cuestiones relacionadas