views:

3185

answers:

12

Suppose I have a string, for example,

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

I want to basically write it multiple times, depending on some integer value.

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

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

EDIT: I know I can easily write my own function to implement this, I was just wondering if there was some weird string operator that I didn't know about

A: 

Sorry, but no, there isn't.

Lasse V. Karlsen
lol. What kind of answer is this? not even any suggestions?
Stimul8d
He said he knew he could write his own code, he was asking if there was something built in, and no, there isn't. Do you mean I should write the code he said he already knew how to write?
Lasse V. Karlsen
+26  A: 

Unfortunately / fortunately, the string class is sealed so you can't inherit from it and overload the * operator. You can create an extension method though:

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);
DrJokepu
Just where I was going! You could probably optimize by using source.Length * multiplier in the StringBuilder ctor
Marc Gravell
Marc's comment was just where *I* was going :)
Jon Skeet
You need (source.Length * multiplier), not just (multiplier)
Marc Gravell
Marc: Are you sure that it means characters and not items?
DrJokepu
Sorry, apparently it is characters.
DrJokepu
Very sure. It allocates a string (of that length) behind the scenes, then mutates it. It doesn't work like a regular List<T> etc.
Marc Gravell
Extension method is ideal here.
Chris Ballance
Nice, thanks guys, I was hoping for something like the pythonesque (@Vasil) but this will do it more nicely that what I was about to do :D
DrG
+6  A: 

You'd have to write a method - of course, with C# 3.0 it could be an extension method:

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

then:

string bar = "abc";
string foo = bar.Repeat(2);
Marc Gravell
Didn't even .NET3 have Enumerable.Repeat?
Will Dean
@Will - .NET 3 was WCF/WPF etc, so no; it does exist in .NET 3.5, but then you'd need to `string.Join` it as well - why not just loop n times? Much more direct.
Marc Gravell
Thanks - I wasn't thinking properly about 3.0 vs 3.5. As to why not just use a loop, surely that's the whole essence of the functional vs imperative debate? I posted a .net 4 answer lower down which I think is not too bad in the 'functional cleverness' vs 'looping obviousness' debate.
Will Dean
+2  A: 
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();
}
Chris Ballance
A: 

not in C#. You can do it in python like so : mystring*n

Vasil
Why would showing an example in a completely unrelated language be helpful?
Jace Rhea
+2  A: 

I'm with DrJokepu on this one, but if for some reason you did want to cheat using built-in functionality then you could do something like this:

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

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

Personally I wouldn't bother though - a custom extension method is much nicer.

LukeH
I never knew there was a cheat like this. =)
Jronny
A: 

Okay, here's my take on the matter:

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

I'm being a bit silly of course, but when I need to have tabulation in code-generating classes, Enumerable.Repeat does it for me. And yeah, the StringBuilder version is fine, too.

Dmitri Nesteruk
+12  A: 

Note that if your "string" is only a single character, there is an overload of the string constructor to handle it:

int multipler = 10;
string TenAs = new string ('A', multipler);
James Curran
+2  A: 

Just for the sake of completeness - here is another way of doing this:

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

I think I pulled that one from Stack Overflow some time ago, so it is not my idea.

A: 

Here's my take on this just for future reference:

    /// <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));
    }
Jronny
I hope you don't really use `ParallelEnumerable` in situations like this. `string.Join` needs to use the elements in order, so parallelizing their generation is uncalled for.
Gabe
@Gabe: Since the items are the same and are really just copies of thisString, there's no need to worry about the ordering here, I guess.
Jronny
+4  A: 

In .NET 4 you can do this:

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

If you have .Net 3.5 but not 4.0, you can use System.Linq's

String.Concat(Enumerable.Range(0, 4).Select(_ => "Hello").ToArray())
Frank Schwieterman
To get a single string you'd still need `String.Concat`, and on 3.5 you'd also need `.ToArray()`. Not the most elegant solution, I'm afraid.
Kobi