web-dev-qa-db-fra.com

Puis-je "multiplier" une chaîne (en C #)?

Supposons que j'ai une chaîne, par exemple,

string snip =  "</li></ul>";

Je veux essentiellement l'écrire plusieurs fois, en fonction d'une valeur entière.

string snip =  "</li></ul>";
int multiplier = 2;

// TODO: magic code to do this 
// snip * multiplier = "</li></ul></li></ul>";

EDIT: Je sais que je peux facilement écrire ma propre fonction pour implémenter cela, je me demandais simplement s'il y avait un opérateur de chaîne étrange que je ne connaissais pas

122
inspite

Dans .NET 4, vous pouvez le faire:

String.Concat(Enumerable.Repeat("Hello", 4))
211
Will Dean

Notez que si votre "chaîne" n'est qu'un seul caractère, il y a une surcharge du constructeur de chaîne pour le gérer:

int multipler = 10;
string TenAs = new string ('A', multipler);
90
James Curran

Malheureusement/heureusement, la classe de chaîne est scellée, vous ne pouvez donc pas en hériter et surcharger l'opérateur *. Vous pouvez cependant créer une méthode d'extension:

public static string Multiply(this string source, int multiplier)
{
   StringBuilder sb = new StringBuilder(multiplier * source.Length);
   for (int i = 0; i < multiplier; i++)
   {
       sb.Append(source);
   }

   return sb.ToString();
}

string s = "</li></ul>".Multiply(10);
60
Tamas Czinege

je suis avec DrJokepu sur celui-ci , mais si pour une raison quelconque vous vouliez tricher en utilisant la fonctionnalité intégrée, vous pourriez faire quelque chose comme ceci:

string snip = "</li></ul>";
int multiplier = 2;

string result = string.Join(snip, new string[multiplier + 1]);

Ou, si vous utilisez .NET 4:

string result = string.Concat(Enumerable.Repeat(snip, multiplier));

Personnellement, cela ne me dérangerait pas - une méthode d'extension personnalisée est beaucoup plus agréable.

11
LukeH

Juste pour être complet - voici une autre façon de procéder:

public static string Repeat(this string s, int count)
{
    var _s = new System.Text.StringBuilder().Insert(0, s, count).ToString();
    return _s;
}

Je pense que j'ai tiré celui-là de Stack Overflow il y a quelque temps, donc ce n'est pas mon idée.

10
user51710

Il faudrait écrire une méthode - bien sûr, avec C # 3.0, cela pourrait être une méthode d'extension:

public static string Repeat(this string, int count) {
    /* StringBuilder etc */ }

puis:

string bar = "abc";
string foo = bar.Repeat(2);
9
Marc Gravell

Un peu tard (et juste pour le plaisir), si vous voulez vraiment utiliser l'opérateur * Pour ce travail, vous pouvez le faire:

public class StringWrap
{
    private string value;
    public StringWrap(string v)
    {
        this.value = v;
    }
    public static string operator *(StringWrap s, int n)
    {
        return s.value.Multiply(n); // DrJokepu extension
    }
}

Et donc:

var newStr = new StringWrap("TO_REPEAT") * 5;

Notez que, tant que vous pouvez trouver un comportement raisonnable pour eux, vous pouvez également gérer d'autres opérateurs via la classe StringWrap, comme \, ^, % Etc ...

P.S.:

Multiply() crédits d'extension à @ DrJokep tous droits réservés ;-)

7
digEmAll

C'est beaucoup plus concis:

new StringBuilder().Insert(0, "</li></ul>", count).ToString()

L'espace de noms using System.Text; doit être importé dans ce cas.

6
user734119

Si vous avez .Net 3.5 mais pas 4.0, vous pouvez utiliser System.Linq

String.Concat(Enumerable.Range(0, 4).Select(_ => "Hello").ToArray())
2
Frank Schwieterman

Puisque tout le monde ajoute ses propres exemples .NET4/Linq, je pourrais aussi bien ajouter les miens. (Fondamentalement, c'est celui de DrJokepu, réduit à une ligne)

public static string Multiply(this string source, int multiplier) 
{ 
    return Enumerable.Range(1,multiplier)
             .Aggregate(new StringBuilder(multiplier*source.Length), 
                   (sb, n)=>sb.Append(source))
             .ToString();
}
2
James Curran
string Multiply(string input, int times)
{
     StringBuilder sb = new StringBuilder(input.length * times);
     for (int i = 0; i < times; i++)
     {
          sb.Append(input);
     }
     return sb.ToString();
}
2
Chris Ballance

Voici mon point de vue à ce sujet pour référence future:

    /// <summary>
    /// Repeats a System.String instance by the number of times specified;
    /// Each copy of thisString is separated by a separator
    /// </summary>
    /// <param name="thisString">
    /// The current string to be repeated
    /// </param>
    /// <param name="separator">
    /// Separator in between copies of thisString
    /// </param>
    /// <param name="repeatTimes">
    /// The number of times thisString is repeated</param>
    /// <returns>
    /// A repeated copy of thisString by repeatTimes times 
    /// and separated by the separator
    /// </returns>
    public static string Repeat(this string thisString, string separator, int repeatTimes) {
        return string.Join(separator, ParallelEnumerable.Repeat(thisString, repeatTimes));
    }
0
Jronny

D'accord, voici mon point de vue sur la question:

public static class ExtensionMethods {
  public static string Multiply(this string text, int count)
  {
    return new string(Enumerable.Repeat(text, count)
      .SelectMany(s => s.ToCharArray()).ToArray());
  }
}

Je suis un peu idiot bien sûr, mais quand j'ai besoin d'avoir une tabulation dans les classes génératrices de code, Enumerable.Repeat le fait pour moi. Et oui, la version StringBuilder est très bien aussi.

0
Dmitri Nesteruk