web-dev-qa-db-fra.com

Fractionner une chaîne / un nombre tous les Nièmes caractères / nombres?

J'ai besoin de diviser un nombre en parties paires, par exemple:
32427237 doit devenir 324 272 37
103092501 doit devenir 103 092 501

Je suis sûr que je pourrais juste pour les prochains chiffres, mais je suis sûr qu'il existe un moyen plus efficace car je ne veux pas manquer les caractères de ces chiffres - les chiffres eux-mêmes peuvent être de n'importe quelle longueur, donc si le nombre était 1234567890 Je voudrais qu'il soit divisé en ces parties 123 456 789 0

J'ai vu des exemples dans d'autres langages comme Python etc mais je ne les comprends pas assez bien pour les convertir en C # - en boucle à travers les caractères puis au troisième en obtenant le précédent et ensuite index pour obtenir la section de la chaîne peut faire le travail, mais je suis ouvert aux suggestions sur la façon de mieux faire cela.

58
RoguePlanetoid

Si vous devez le faire à de nombreux endroits de votre code, vous pouvez créer une méthode d'extension sophistiquée:

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

}

Vous pouvez ensuite l'utiliser comme ceci:

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

La sortie est 324 272 37 comme voulu.

109
Martin Liversage

Vous pouvez utiliser une simple boucle for pour insérer des blancs à chaque nième position:

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();
8
Dirk Vollmar

Règles LINQ:

var input = "1234567890";
var partSize = 3;

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

MISE À JOUR:

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

Un très moyen simple de le faire (pas le plus efficace, mais pas plus lent que le plus efficace).

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

Voici un suppléant

    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;
    }
5
Binary Worrier

C'est une demi-décennie de retard mais:

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()));
5
Tyress

La méthode de fractionnement:

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

Pour rejoindre en retour une chaîne, délimitée par des espaces:

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

Edit: j'aime mieux la solution Martin Liversage :)

Edit 2: correction d'un bug.

Edit 3: Ajout de code pour rejoindre la chaîne.

3
Fábio Batista

Je ferais quelque chose comme ça, même si je suis sûr qu'il existe d'autres moyens. Devrait fonctionner assez 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();
}
2
steinar

J'aime ça parce que c'est cool, mais pas super efficace:

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();
2
Sam Saffron

Essaye ça:

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

Si vous savez que la longueur de la chaîne entière est exactement divisible par la taille de la pièce, utilisez alors:

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

Mais s'il y a une possibilité que la chaîne entière puisse avoir un morceau fractionnaire à la fin, vous avez besoin d'un peu plus de sophistication:

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

Dans ces exemples, les parties seront un IEnumerable, mais vous pouvez ajouter .ToArray () ou .ToList () à la fin au cas où vous souhaiteriez une chaîne [] ou List <string>.

2
Dave Lampert

Une belle implémentation utilisant les réponses à d'autres questions 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/53876

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

1
crokusek

Pour diviser une chaîne et renvoyer une liste de chaînes avec un certain nombre de caractères par place, voici ma fonction:

public List<string> SplitStringEveryNth(string input, int chunkSize)
    {
        var output = new List<string>();
        var flag = chunkSize;
        var tempString = string.Empty;
        var lenght = input.Length;
        for (var i = 0; i < lenght; i++)
        {
            if (Int32.Equals(flag, 0))
            {
                output.Add(tempString);
                tempString = string.Empty;
                flag = chunkSize;
            }
            else
            {
                tempString += input[i];
                flag--;
            }

            if ((input.Length - 1) == i && flag != 0)
            {
                tempString += input[i];
                output.Add(tempString);
            }
        }
        return output;
    }
0
António Sobrinho

Cela pourrait être hors sujet car je ne sais pas pourquoi vous souhaitez formater les chiffres de cette façon, veuillez donc simplement ignorer ce post s'il n'est pas pertinent ...

La façon dont un entier est affiché diffère selon les cultures. Vous devez le faire de manière indépendante locale afin qu'il soit plus facile de localiser vos modifications ultérieurement.

int.ToString prend différents paramètres que vous pouvez utiliser pour formater pour différentes cultures. Le paramètre "N" vous donne un format standard pour le regroupement spécifique à la culture.

formatage steve x string est également une excellente ressource.

0
simendsjo