408 votes

Existe-t-il un moyen simple de renvoyer une chaîne de caractères répétée un nombre X de fois ?

J'essaie d'insérer un certain nombre d'indentations avant une chaîne de caractères en fonction de la profondeur d'un élément et je me demande s'il existe un moyen de renvoyer une chaîne de caractères répétée X fois. Exemple :

string indent = "---";
Console.WriteLine(indent.Repeat(0)); //would print nothing.
Console.WriteLine(indent.Repeat(1)); //would print "---".
Console.WriteLine(indent.Repeat(2)); //would print "------".
Console.WriteLine(indent.Repeat(3)); //would print "---------".

9 votes

Je ne suis pas sûr que ce soit applicable, mais vous pourriez vouloir regarder le site de la IndentedTextWriter également.

696voto

Ahmad Mageed Points 44495

Si vous avez seulement l'intention de répéter le même caractère, vous pouvez utiliser la fonction constructeur de chaînes qui accepte un caractère et le nombre de fois qu'il doit être répété. new String(char c, int count) .

Par exemple, pour répéter un tiret cinq fois :

string result = new String('-', 5);
Output: -----

12 votes

Merci de m'avoir rappelé cette belle petite fonctionnalité. Je pense qu'elle était perdue dans un coin de mon esprit.

3 votes

Puisque le métacaractère de tabulation ' \t est un caractère, cela fonctionne également pour l'indentation.

101 votes

Il s'agit d'une astuce très utile du C#, mais le titre de la question porte sur une chaîne de caractères (et non un caractère). Les autres réponses en dessous de celle-ci répondent effectivement à la question, mais sont notées beaucoup plus bas. Je n'essaie pas de manquer de respect à la réponse d'Ahmad, mais je pense que soit le titre de cette question devrait être modifié (si la question concerne réellement les caractères), soit les autres réponses devraient vraiment être upvoted (et pas celle-ci).

315voto

Dan Tao Points 60518

Si vous utilisez .NET 4.0, vous pourriez utiliser string.Concat en même temps que Enumerable.Repeat .

int N = 5; // or whatever
Console.WriteLine(string.Concat(Enumerable.Repeat(indent, N)));

Sinon, je choisirais quelque chose comme La réponse d'Adam .

La raison pour laquelle j'ai généralement ne serait pas conseillent d'utiliser Réponse d'Andrey est simplement que le ToArray() introduit une surcharge superflue qui est évitée avec l'option StringBuilder approche suggérée par Adam. Cela dit, au moins, elle fonctionne sans nécessiter .NET 4.0, et elle est rapide et facile (et ne va pas vous tuer si l'efficacité n'est pas trop une préoccupation).

3 votes

Cela fonctionnera bien avec les chaînes de caractères, par exemple si vous devez concaténer des espaces insécables (&nbsp ;). Mais je suppose que le constructeur de chaînes sera plus rapide si vous avez affaire à un caractère...

1 votes

Le constructeur de chaînes de caractères ne fonctionne que pour un seul caractère. L'option consistant à utiliser Concat Repeat fonctionnera pour les chaînes de caractères.

4 votes

Merci de répondre à la question du titre réel !

51voto

Adam Robinson Points 88472
public static class StringExtensions
{
    public static string Repeat(this string input, int count)
    {
        if (!string.IsNullOrEmpty(input))
        {
            StringBuilder builder = new StringBuilder(input.Length * count);

            for(int i = 0; i < count; i++) builder.Append(input);

            return builder.ToString();
        }

        return string.Empty;
    }
}

7 votes

Autant passer input.Length * count à la StringBuilder constructeur, vous ne pensez pas ?

0 votes

Adam, je vois que vous avez pris la peine de tester la nullité de l'entrée avant de l'ajouter au compte, mais que vous avez ensuite laissé passer l'occasion, en comptant sur Append pour ne rien faire étant donné la nullité. IMHO, c'est moins qu'évident : si null est une entrée possible, pourquoi ne pas le tester dès le départ, et retourner une chaîne vide ?

2 votes

@AdamRobinson Est-ce que renvoyer une chaîne vide à la place d'un null est souhaitable ? Je remplacerais return string.empty avec return input de cette façon, vous obtenez null in/null out, et empty in/empty out.

25voto

Steve Townsend Points 36948

Utilisez String.PadLeft si la chaîne de caractères souhaitée ne contient qu'un seul caractère.

public static string Indent(int count, char pad)
{
    return String.Empty.PadLeft(count, pad);
}

Crédit dû ici

1 votes

KISS. Pourquoi avons-nous besoin de StringBuilders et d'extensions, de toute façon ? C'est un problème très simple.

1 votes

Je ne sais pas, cela semble résoudre le problème tel qu'il est formulé avec une certaine élégance. Et au fait, qui appelez-vous "S" ? :-)

9 votes

Mais n'est-ce pas simplement une version moins évidente de le site string qui prend un char et un int ?

12voto

Thomas Levesque Points 141081

J'opterais pour la réponse de Dan Tao, mais si vous n'utilisez pas .NET 4.0, vous pouvez faire quelque chose comme ça :

public static string Repeat(this string str, int count)
{
    return Enumerable.Repeat(str, count)
                     .Aggregate(
                        new StringBuilder(str.Length * count),
                        (sb, s) => sb.Append(s))
                     .ToString();
}

4 votes

Si je trouve ce bout de phrase dans mon projet, je me demanderai qui a violé le KISS et pourquoi... joli autrement.

0 votes

Votre new StringBuilder devrait au moins passer dans str.Length*count .

0 votes

@NetMage bon point. C'est fait !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X