我试图在基于项深度的字符串之前插入一定数量的缩进,我想知道是否有一种方法可以返回一个重复X次的字符串。例子:

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 "---------".

使用字符串。PadLeft,如果你想要的字符串只包含一个字符。

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

这里的信用


public static class StringExtensions
{
    public static string Repeat(this string input, int count)
    {
        if (string.IsNullOrEmpty(input) || count <= 1)
            return input;

        var builder = new StringBuilder(input.Length * count);

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

        return builder.ToString();
    }
}

如果你使用。net 4.0,你可以使用字符串。与enumerable连接。重复。

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

否则我会用亚当的答案。

我通常不建议使用Andrey的答案的原因很简单,ToArray()调用引入了多余的开销,而Adam建议的StringBuilder方法可以避免这些开销。也就是说,至少它不需要。net 4.0就能工作;而且它又快又简单(如果效率不是太重要的话,也不会要了你的命)。


你可以创建一个ExtensionMethod来做这件事!

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

或者使用@丹涛解决方案:

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

    return string.Concat(Enumerable.Repeat(indent, N))
  }
}

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

如果你只想重复相同的字符,你可以使用string构造函数接受一个字符和重复次数new string (char c, int count)。

例如,重复五次破折号:

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

我想要Dan Tao的答案,但是如果你没有使用。net 4.0,你可以这样做:

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

另一种方法是将string视为IEnumerable<char>,并使用通用扩展方法将集合中的项乘以指定的因子。

public static IEnumerable<T> Repeat<T>(this IEnumerable<T> source, int times)
{
    source = source.ToArray();
    return Enumerable.Range(0, times).SelectMany(_ => source);
}

在你的例子中:

string indent = "---";
var f = string.Concat(indent.Repeat(0)); //.NET 4 required
//or
var g = new string(indent.Repeat(5).ToArray());

没想到居然没人走老路。 我并没有对这段代码做任何声明,只是为了好玩:

public static string Repeat(this string @this, int count)
{
    var dest = new char[@this.Length * count];
    for (int i = 0; i < dest.Length; i += 1)
    {
        dest[i] = @this[i % @this.Length];
    }
    return new string(dest);
}

不知道这将如何执行,但这是一段简单的代码。(我可能让它看起来比实际更复杂。)

int indentCount = 3;
string indent = "---";
string stringToBeIndented = "Blah";
// Need dummy char NOT in stringToBeIndented - vertical tab, anyone?
char dummy = '\v';
stringToBeIndented.PadLeft(stringToBeIndented.Length + indentCount, dummy).Replace(dummy.ToString(), indent);

或者,如果您知道期望的最大层数,则可以声明一个数组并在其中建立索引。你可能想让这个数组是静态的或者是常量。

string[] indents = new string[4] { "", indent, indent.Replace("-", "--"), indent.Replace("-", "---"), indent.Replace("-", "----") };
output = indents[indentCount] + stringToBeIndented;      

我没有足够的代表来评论亚当的回答,但在我看来,最好的方法是这样的:

public static string RepeatString(string content, int numTimes) {
        if(!string.IsNullOrEmpty(content) && numTimes > 0) {
            StringBuilder builder = new StringBuilder(content.Length * numTimes);

            for(int i = 0; i < numTimes; i++) builder.Append(content);

            return builder.ToString();
        }

        return string.Empty;
    }

您必须检查numTimes是否大于0,否则会出现异常。


最高性能的字符串解决方案

string result = new StringBuilder().Insert(0, "---", 5).ToString();

我喜欢你给出的答案。我过去也用过同样的方法:

"".PadLeft(3*Indent,'-')

这将实现创建缩进,但技术上的问题是重复一个字符串。如果字符串缩进是像>-<这样的东西,那么这个和接受的答案一样将不起作用。在这种情况下,c0rd使用StringBuilder的解决方案看起来不错,尽管StringBuilder的开销实际上可能不是最高性能的。一种选择是构建一个字符串数组,用缩进字符串填充它,然后连接它。一点点:

int Indent = 2;
        
string[] sarray = new string[6];  //assuming max of 6 levels of indent, 0 based

for (int iter = 0; iter < 6; iter++)
{
    //using c0rd's stringbuilder concept, insert ABC as the indent characters to demonstrate any string can be used
    sarray[iter] = new StringBuilder().Insert(0, "ABC", iter).ToString();
}

Console.WriteLine(sarray[Indent] +"blah");  //now pretend to output some indented line

我们都喜欢聪明的解决方案,但有时简单是最好的。


我没有看到这个解。我发现在我目前的软件开发工作中,它更简单:

public static void PrintFigure(int shapeSize)
{
    string figure = "\\/";
    for (int loopTwo = 1; loopTwo <= shapeSize - 1; loopTwo++)
    {
        Console.Write($"{figure}");
    }
}

对于许多场景,这可能是最简洁的解决方案:

public static class StringExtensions
{
    public static string Repeat(this string s, int n)
        => new StringBuilder(s.Length * n).Insert(0, s, n).ToString();
}

用法是:

text = "Hello World! ".Repeat(5);

这建立在其他答案的基础上(特别是@c0rd)。除了简单之外,它还具有以下特性,不是所有讨论的其他技术都具有这些特性:

重复任意长度的字符串,而不仅仅是字符(根据OP的要求)。 通过存储预分配有效使用StringBuilder。


你可以重复你的字符串(如果它不是一个单一的字符)并连接结果,像这样:

String.Concat(Enumerable.Repeat("---", 5))

重复打印一行。

Console.Write(new string('=', 30) + "\n");

==============================


对于一般使用,涉及StringBuilder类的解决方案最适合重复多字符字符串。它被优化为处理大量字符串的组合,这是简单的连接所不能做到的,而且手工很难或不可能更有效地做到。这里显示的StringBuilder解决方案使用O(N)次迭代来完成,这是与重复次数成比例的固定速率。

然而,对于非常大量的重复,或者必须从它中挤出高水平的效率,更好的方法是执行类似StringBuilder的基本功能,但从目标而不是从原始字符串生成额外的副本,如下所示。

    public static string Repeat_CharArray_LogN(this string str, int times)
    {
        int limit = (int)Math.Log(times, 2);
        char[] buffer = new char[str.Length * times];
        int width = str.Length;
        Array.Copy(str.ToCharArray(), buffer, width);

        for (int index = 0; index < limit; index++)
        {
            Array.Copy(buffer, 0, buffer, width, width);
            width *= 2;
        }
        Array.Copy(buffer, 0, buffer, width, str.Length * times - width);

        return new string(buffer);
    }

这使得源/目标字符串的长度每次迭代都翻倍,从而节省了每次遍历原始字符串时重置计数器的开销,而不是顺利地读取和复制现在更长的字符串,这是现代处理器可以更有效地完成的事情。

它使用以2为底的对数来计算需要将字符串长度翻倍多少次,然后继续这样做多少次。由于要复制的剩余部分现在小于它要复制的总长度,因此它可以简单地复制它已经生成的内容的子集。

我使用了Array.Copy()方法,而不是使用StringBuilder,因为将StringBuilder的内容复制到自身中会在每次迭代中产生带有该内容的新字符串的开销。Array.Copy()避免了这种情况,同时仍然以极高的效率进行操作。

这个解决方案需要O(1 + log N)次迭代才能完成,这个速率随着重复次数的增加呈对数增长(重复次数加倍等于一次额外的迭代),这比其他方法节省了大量的时间,其他方法按比例增加。


添加扩展方法,我正在使用我的所有项目:

public static string Repeat(this string text, int count)
{
    if (!String.IsNullOrEmpty(text))
    {
        return String.Concat(Enumerable.Repeat(text, count));
    }
    return "";
}

希望有人能利用它…


字符串和字符[版本1]

string.Join("", Enumerable.Repeat("text" , 2 ));    
//result: texttext

字符串和字符[版本2]:

String.Concat(Enumerable.Repeat("text", 2));
//result: texttext

字符串和字符[版本3]

new StringBuilder().Insert(0, "text", 2).ToString(); 
//result: texttext

识字课只有:

'5' * 3; 
//result: 555

识字课只有:

new string('5', 3);
//result: 555

扩展方法:

(工作更快-更好的WEB)

public static class RepeatExtensions
{
    public static string Repeat(this string str, int times)
    {
        var a = new StringBuilder();
        
        //Append is faster than Insert
        ( () => a.Append(str) ).RepeatAction(times) ;
        
        return a.ToString();
    }

    public static void RepeatAction(this Action action, int count)
    {
        for (int i = 0; i < count; i++)
        {
            action();
        }
    }

}

用法:

 var a = "Hello".Repeat(3); 
 //result: HelloHelloHello

使用新字符串。创建函数时,我们可以预先分配合适的大小,并使用Span<char>在循环中复制单个字符串。

我怀疑这可能是最快的方法,因为根本没有额外的分配:字符串被精确分配。

 public static string Repeat(this string source, int times)
 {
     return string.Create(source.Length * times, source, RepeatFromString);
 }
 
 private static void RepeatFromString(Span<char> result, string source)
 {
     ReadOnlySpan<char> sourceSpan = source.AsSpan();
     for (var i = 0; i < result.Length; i += sourceSpan.Length)
         sourceSpan.CopyTo(result.Slice(i, sourceSpan.Length));
 }

dotnetfiddle