tags:

views:

152

answers:

8

I'm trying to insert a certain number of indentations before a string based on an items depth and I'm wondering if there is a way to return a string repeated X times. Example:

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 "---------".
+3  A: 

Use String.PadLeft, if your desired string contains only a single char.

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

Credit due here

Steve Townsend
KISS. What do we need StringBuilders and extensions for, anyway? This is a very simple problem.
DOK
I dunno, this seems to solve the problem as phrased with some elegance. And btw, who are you calling 'S'? :-)
Steve Townsend
But isn't this really just a less obvious version of [the `string` constructor that takes a `char` and an `int`](http://msdn.microsoft.com/en-us/library/xsa4321w.aspx)?
Dan Tao
It would look nicer with String.Empty instead of ""... otherwise, good solution ;)
Thomas Levesque
@Dan - yes, that's clearly the best here.
Steve Townsend
@Steve BTW the [`String.PadLeft`](http://msdn.microsoft.com/en-us/library/92h5dc07.aspx) arguments are reversed. The `count` comes before the padding character.
Ahmad Mageed
@Ahmad - fixed, thx
Steve Townsend
+4  A: 
public static class StringExtensions
{
    public static string Repeat(this string input, int count)
    {
        StringBuilder builder = new StringBuilder(
            (input == null ? 0 : input.Length) * count);

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

        return builder.ToString();
    }
}
Adam Robinson
Beat me to it, exactly what I was going to say.
Will Eddins
Might as well pass `input.Length * count` to the `StringBuilder` constructor, don't you think?
Dan Tao
@Dan: Does seem like a good idea, doesn't it?
Adam Robinson
And if you pass `input.Length * count` to the `StringBuilder` constructor, you could skip the `StringBuilder` altogether and create a char[] of the right size right away.
dtb
@dtb: I'm curious why you'd want to do that. I can't imagine that it would be much (if any) faster than using a `StringBuilder`, and the code would be less transparent.
Adam Robinson
+3  A: 

If you're using .NET 4.0, you could use string.Concat together with Enumerable.Repeat.

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

Otherwise I'd go with something like Adam's answer.

The reason I generally wouldn't advise using Andrey's answer is simply that the ToArray() call introduces superfluous overhead that is avoided with the StringBuilder approach suggested by Adam. That said, at least it works without requiring .NET 4.0; and it's quick and easy (and isn't going to kill you if efficiency isn't too much of a concern).

Dan Tao
A: 

You can create an ExtensionMethod to do that!

public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    string ret = "";

    for (var x = 0; x < count; x++)
    {
      ret += str;
    }

    return ret;
  }
}

Or using @Dan Tao solution:

public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    if (count == 0)
      return "";

    return string.Concat(Enumerable.Repeat(indent, N))
  }
}
Zote
See my comment to Kyle's answer
Thomas Levesque
A: 
        string indent = "---";
        string n = string.Concat(Enumerable.Repeat(indent, 1).ToArray());
        string n = string.Concat(Enumerable.Repeat(indent, 2).ToArray());
        string n = string.Concat(Enumerable.Repeat(indent, 3).ToArray());
Andrey
@Adam: I guess you'd need to do that pre-.NET 4.0.
Dan Tao
A: 

Something to this effect?

string Repeat(string, count)
{
    string out="";
    for(int i=0;i<count;i++)
        out = out+string;
    return out;
}

called:

Console.WriteLine(Repeat("asfasf",4));
Kyle
Never use string concatenation in a loop, unless you know for sure there will be a small number of iterations. It can put a lot of pressure on the GC by creating a lot of temporary string instances. Use a StringBuilder instead
Thomas Levesque
Awesome, good to know!
Kyle
+12  A: 

If you only intend to repeat the same character you can use the string constructor that accepts a char and the number of times to repeat it new String(char c, int count).

For example, to repeat a dash five times:

string result = new String('-', 5); // -----
Ahmad Mageed
Thanks for reminding me about this nice little feature. I think it was lost in the corner of my mind.
Chris Shouts
Awesome, i had no idea.
Abe Miessler
the classes in the framework never cease to amaze..there is just so much done for us already in there...
desigeek
+1  A: 

I would go for Dan Tao's answer, but if you're not using .NET 4.0 you can do something like that:

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