2010-11-09 16 views
45

Ho bisogno di dividere un numero in più parti, anche ad esempio:
32.427.237 deve diventare 324 272 37
103.092.501 esigenze di diventare 103 092 501Divisione di una stringa/numero ogni n. Carattere/numero?

sono sicuro che ho potuto solo per-next i numeri, ma Sono sicuro che c'è un modo più efficiente in quanto non voglio perdere i caratteri di questi numeri - i numeri stessi possono essere di qualsiasi lunghezza, quindi se il numero fosse 1234567890 lo vorrei dividere in queste parti 123 456 789 0

Ho visto esempi in altri linguaggi come Python ecc., Ma non li capisco abbastanza bene per convertirli in C# - looping attraverso i caratteri e poi al terzo ottenendo il precedente e poi quell'indice per ottenere la sezione della stringa potrebbe fare il lavoro, ma sono aperto a suggerimenti su come ottenerlo meglio.

+1

Vuoi dividere la stringa in tre stringhe separate, o r vuoi inserire spazi? –

+2

http://stackoverflow.com/questions/3760152/split-string-to-equal-length-substrings-in-java. Tutte le risposte sono in java ma puoi facilmente portarlo in C#. – Emil

+0

Sarebbero tre stringhe separate – RoguePlanetoid

risposta

90

Se avete a che fare che in molti luoghi nel codice è possibile creare un metodo di estensione di fantasia:

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

} 

È quindi possibile utilizzare in questo modo:

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

L'uscita è 324 272 37, se lo desideri.

+1

+1 Solo soluzione (ancora) che usa un 'n' come parametro. – st0le

+2

Il metodo di estensione IMHO qui è eccessivo. Il "numero" in questione da dividere è un tipo specifico di cosa, ad es. un numero d'ordine Se si potesse limitare il metodo di estensione per applicare solo a numeri d'ordine, allora va bene. Poiché è possibile applicarlo a qualsiasi entità che si trova in una stringa, ciò interrompe l'incapsulamento. –

+0

In effetti ho pensato a un metodo che permettesse di dividere una stringa in una parte di qualsiasi dimensione: proveremo questo! – RoguePlanetoid

3

Uno molto modo semplice per farlo (non il più efficace, ma poi non ordini di grandezza più lento rispetto alla più efficiente).

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 supplente

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 versione 'n' generica sarebbe meglio. – st0le

+0

@ st0le: Non funziona la scienza missilistica su chunksize variabile :) –

7

Si potrebbe utilizzare un semplice ciclo for per inserire spazi vuoti in ogni posizione n-esima:

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

Questo è simile a quello che stavo per creare, ma era interessato a vedere altre alternative – RoguePlanetoid

0

Questo potrebbe essere off topic come io non so perché si desidera formattare i numeri in questo modo, quindi per favore basta ignorare questo post se non è rilevante ...

Come è mostrato un intero differisce tutta diversa culture. Dovresti farlo in maniera indipendente e locale, quindi è più facile localizzare le tue modifiche in un secondo momento.

int.ToString accetta diversi parametri che è possibile utilizzare per formattare per culture diverse. Il parametro "N" fornisce un formato standard per il raggruppamento specifico della cultura.

steve x string formatting è anche una grande risorsa.

+0

Sono solo numeri che non obbedisco a nessun tipo di normale formattazione dei numeri ed è per questo che ho menzionato stringa/numero mentre li userò per qualcosa che richiede questa particolare formattazione. – RoguePlanetoid

3

Il metodo splitting:

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

Per unire di nuovo come una stringa, delimitata da spazi:

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

Edit: mi piace Martin soluzione Liversage meglio :)

Edit 2: Risolto un bug

Modifica 3: codice aggiunto per unire la stringa indietro.

2

Vorrei fare qualcosa del genere, anche se sono sicuro che ci sono altri modi. Dovrebbe funzionare abbastanza bene.

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

Mi piace questa causa il suo fresco, anche se non super efficiente:

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

Sono parziale a Linq, ma l'efficienza è un requisito - grazie per l'esempio anche se – RoguePlanetoid

5

regole LINQ:

var input = "1234567890"; 
var parts = 3; 

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

aggiornamento:

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' è parte di Reactive Extensions per .NET (Rx): http://msdn.microsoft.com /en-us/devlabs/ee794896.aspx. Dovrai scaricarlo e installarlo per far funzionare il codice. –

+0

Grazie non avevo mai visto BufferWithCount prima - ora so perché - Ho installato Rx quindi potrebbe essere utile per qualcos'altro. – RoguePlanetoid

0

provare questo:

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

Se si sa che la lunghezza di tutta la stringa è esattamente divisibile per la dimensione parte, quindi utilizzare:

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

Ma se c'è una possibilità l'intera stringa può avere un pezzo frazionaria alla fine, è necessario po 'più sofisticato:

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))); 

in questi esempi, le parti sarà un IEnumerable, ma è possibile aggiungere .ToArray() o ToList() alla fine nel caso in cui si desidera una string [] o List <string> valore.

+0

Dovresti aggiungere la tua risposta a una domanda già risposta se pensi di aggiungere valore alla risposta accettata. Non sembra che sia così. –

+0

Non capisco. Questa era la decima risposta a questa domanda, e solo la terza che può essere fatta in una singola istruzione (usando Linq), e credo di essere la più efficiente di quelle 3. Ho sbagliato ad aggiungere questa risposta diversa e possibilmente migliore ? –

2

Questa è la metà di un decennio di ritardo ma:

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

Non è mai troppo tardi per una risposta, mi sono chiesto se c'è una soluzione LINQ ed eccola qui! – RoguePlanetoid

Problemi correlati