140

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

inspite
  • 27,551
  • 21
  • 73
  • 91
  • Possible duplicate of [Is there an easy way to return a string repeated X number of times?](http://stackoverflow.com/questions/3754582/is-there-an-easy-way-to-return-a-string-repeated-x-number-of-times) – Michael Freidgeim May 30 '16 at 04:32

13 Answers13

228

In .NET 4 you can do this:

String.Concat(Enumerable.Repeat("Hello", 4))
Will Dean
  • 37,648
  • 10
  • 84
  • 116
  • 9
    And it's not much more in .NET 3.5: String.Concat(Enumerable.Repeat("Hello", 4).ToArray()) – Mark Foreman Sep 03 '12 at 00:54
  • 4
    I don't think it's elegant at all. In python the code to do this is: snip * multiplier (It's not horrible.. but neither is it beautiful). – demented hedgehog Jun 02 '15 at 02:56
  • 9
    @dementedhedgehog I know you acknowledge your own dementia, but even suffering as you do, you might be able to see that a Python example wouldn't have made a very good answer to a C# question... I think most of us can see that language selection is always a compromise, and pretty much any answer to any question could be footnoted with advocacy, either for or against. – Will Dean Jun 02 '15 at 21:45
  • 1
    @will dean: I was just referring to Matthew Nichols statement about the elegance of the code you have there. As far as I can tell your code is elegant for C#, as it currently stands, for this problem. The point I'm trying to make is: (I believe) it would be very easy (for microsoft, as strings are sealed) to extend C# to overload the * operator to allow int * string multiplication. Which would then actually be elegant in some universal sense, imho, not just elegant within the context of the constraints imposed by C# as it exists at the moment. – demented hedgehog Jun 03 '15 at 03:20
  • 1
    @dementedhedgehog To me, that goes against what binary `operator*` represents. To each their own, I guess. – TEK Jan 15 '17 at 14:25
  • Yeah.. I can appreciate that. Potentially breaks strong typing... could lead to weird errors if you weren't careful. (I still like python grammar+stdlibs much better for string manipulation). – demented hedgehog Jan 16 '17 at 00:45
108

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
  • 95,648
  • 35
  • 171
  • 253
62

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);
Tamas Czinege
  • 110,351
  • 39
  • 146
  • 173
12

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

Or, if you're using .NET 4:

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

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

Community
  • 1
  • 1
LukeH
  • 242,140
  • 52
  • 350
  • 400
10

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.

user51710
  • 1,153
  • 2
  • 10
  • 20
9

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
  • 927,783
  • 236
  • 2,422
  • 2,784
  • Didn't even .NET3 have Enumerable.Repeat? – Will Dean Jul 21 '10 at 09:01
  • @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 Jul 21 '10 at 19:26
  • 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 Jul 21 '10 at 19:56
8

A little late (and just for fun), if you really want to use the * operator for this work, you can do this :

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

And so:

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

Note that, as long as you are able to find a reasonable behavior for them, you can also handle other operators through StringWrap class, like \ , ^ , % etc...

P.S.:

Multiply() extension credits to @DrJokepu all rights reserved ;-)

Community
  • 1
  • 1
digEmAll
  • 53,114
  • 9
  • 109
  • 131
8

This is a lot more concise:

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

The namespace using System.Text; should be imported in this case.

Evgeny Bobkin
  • 3,675
  • 2
  • 15
  • 19
user734119
  • 83
  • 1
  • 5
2

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
  • 23,338
  • 15
  • 87
  • 123
  • 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 Jul 22 '10 at 05:41
2

Since everyone is adding their own .NET4/Linq examples, I might as well add my own. (Basically, it DrJokepu's, reduced to a one-liner)

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();
}
James Curran
  • 95,648
  • 35
  • 171
  • 253
2
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
  • 32,056
  • 25
  • 101
  • 147
0

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
  • 1,806
  • 3
  • 29
  • 40
  • 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 Jul 22 '10 at 05:57
  • @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 Jul 23 '10 at 08:07
  • I agree with many teachers in the field that it is usually is good to code to say what you mean. There is no benefit to say you want this parallel and only secretly think "Well, I know it won't be parallel in this particular case anyway" – sehe Mar 21 '11 at 10:33
  • I think making it parallel makes it faster, or please enlighten me. That's why I'm converting this to ParallelEnumerable, thus I think I code to say what I mean... Thanks. – Jronny Nov 22 '11 at 03:10
0

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
  • 20,962
  • 21
  • 90
  • 152