C #에서 문자열을 "곱셈"할 수 있습니까?


136

예를 들어 문자열이 있다고 가정합니다.

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

정수 값에 따라 기본적으로 여러 번 쓰고 싶습니다.

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

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

편집 : 나는 이것을 구현하기 위해 쉽게 내 자신의 함수를 작성할 수 있다는 것을 알고있다. 나는 모르는 이상한 문자열 연산자가 있는지 궁금해했다.


답변:


222

.NET 4에서는 다음을 수행 할 수 있습니다.

String.Concat(Enumerable.Repeat("Hello", 4))

9
그리고 .NET 3.5에는 그다지 많지 않습니다 : String.Concat (Enumerable.Repeat ( "Hello", 4) .ToArray ())
— Mark Foreman

4
나는 그것이 우아하다고 생각하지 않습니다. 파이썬에서 이것을 수행하는 코드는 다음과 같습니다 : snip * multiplier (끔찍하지 않습니다.
— demented 고슴도치

7
@dementedhedgehog 나는 당신이 당신 자신의 치매를 인정한다는 것을 알고 있지만, 당신이하는 것처럼 고통 스럽지만, 파이썬 예제가 C # 질문에 대해 아주 좋은 대답을하지 못했을 수도 있습니다 ... 우리 대부분은 볼 수 있다고 생각합니다 언어 선택은 항상 타협이며, 모든 질문에 대한 답변은 옹호와 함께 또는 옹호 할 수 있습니다.
— Will Dean

1
@ will dean : 나는 당신이 가지고있는 코드의 우아함에 관한 Matthew Nichols의 진술을 언급하고있었습니다. 내가 알 수있는 한,이 문제에 대한 코드는 현재 C #에 적합합니다. 내가하려고하는 요점은 다음과 같습니다. (Microsoft가 문자열을 봉인 한 것처럼) C #을 확장하여 int * 문자열 곱셈을 허용하도록 연산자를 오버로드하는 것이 매우 쉽다고 생각합니다. 그러면 C #이 현재 존재하는 제약 조건의 맥락 내에서 우아하지 않고 보편적 인 의미로 imho가 실제로 우아합니다.
— demented 고슴도치

@dementedhedgehog 저에게는 바이너리가 operator*나타내는 것과 반대 입니다. 그들 각자에게, 나는 추측한다.
— TEK

99

"문자열"이 단일 문자 인 경우이를 처리하기 위해 문자열 생성자가 오버로드됩니다.

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

이것은 정말 프로입니다.
— Zaven Zareyan

61

불행히도 / 운 좋게도 문자열 클래스는 봉인되어 있으므로 상속 할 수 없으며 * 연산자를 오버로드 할 수 없습니다. 그래도 확장 방법을 만들 수 있습니다.

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

5
내가가는 곳! StringBuilder ctor
— Marc Gravell

2
마크의 의견이었다 어디서 나는 :) 가고 있었다
— 존 소총

1
당신은 (승수)가 아닌 (source.Length * multiplier)가 필요합니다
— Marc Gravell

1
매우 확신하다. 씬 뒤에 문자열을 할당 한 다음 변경합니다. 일반적인 List <T>와 같이 작동하지 않습니다.
— Marc Gravell

1
확장 방법이 이상적입니다.
— Chris Ballance

12

나는 이것에 DrJokepu와 함께 있지만 어떤 이유로 든 내장 기능을 사용하여 속이기를 원한다면 다음과 같이 할 수 있습니다.

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

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

또는 .NET 4를 사용하는 경우 :

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

개인적으로 나는 귀찮게하지 않을 것입니다-사용자 정의 확장 방법이 훨씬 좋습니다.


1
나는 이런 속임수가 있다는 것을 몰랐다. =)
— Jronny

10

완벽을 기하기 위해 여기에 또 다른 방법이 있습니다.

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

나는 얼마 전에 Stack Overflow에서 그 것을 뽑았다 고 생각하기 때문에 내 생각이 아닙니다.


9

C # 3.0을 사용하는 방법은 물론 확장 방법이 될 수있는 방법을 작성해야합니다.

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

그때:

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

.NET3조차도 Enumerable.Repeat이 없었습니까?
— Will Dean

@Will-.NET 3은 WCF / WPF 등이 아니 었습니다. 그것은 .NET 3.5에 존재하지만 당신도 그것을 필요로 할 것입니다 string.Join-왜 n 번 반복하지 않습니까? 훨씬 더 직접적입니다.
— Marc Gravell

감사합니다-3.0 대 3.5에 대해 제대로 생각하지 않았습니다. 루프를 사용하지 않는 이유에 관해서는 이것이 기능적 토론과 명령 토론의 본질입니까? 나는 .net 4 답변을 아래로 게시했습니다.
— Will Dean

8

*이 작업에 연산자를 실제로 사용하려면 조금 늦게 (그리고 단지 재미로) 다음과 같이하십시오.

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

그래서 :

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

만큼 당신이 그들을 위해 적절한 행동을 찾을 수 있습니다, 당신은 또한을 통해 다른 연산자를 처리 할 수있는, 그 참고 StringWrap클래스, 같은 \, ^, %등 ...

추신:

Multiply()@DrJokepu에 대한 확장 크레딧 모든 권리 보유 ;-)


7

이것은 훨씬 간결합니다.

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

using System.Text;이 경우 네임 스페이스 를 가져와야합니다.


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

2

.Net 3.5이지만 4.0이 아닌 경우 System.Linq를 사용할 수 있습니다

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

단일 문자열을 얻으려면 여전히 필요 String.Concat하며 3.5에서는 또한 필요합니다 .ToArray(). 가장 우아한 해결책은 아닙니다.
— Kobi

2

모든 사람들이 자신의 .NET4 / Linq 예제를 추가하고 있기 때문에 나 자신도 추가 할 수 있습니다. (기본적으로 Drokeke 's, 1-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();
}

0

알았어, 여기 내가 맡은 문제가있다.

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

물론 약간 어리석은 일이지만 코드 생성 클래스에서 표를 작성해야 할 때 Enumerable.Repeat가 대신합니다. 그리고 예, StringBuilder 버전도 좋습니다.


0

다음은 나중에 참조 할 수 있도록 여기에 대한 내용입니다.

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

ParallelEnumerable이런 상황 에서는 실제로 사용하지 않기를 바랍니다 . string.Join요소를 순서대로 사용해야하므로 생성을 병렬화 할 필요가 없습니다.
— Gabe

@ Gabe : 항목은 동일하고 실제로이 String의 사본이므로 주문에 대해 걱정할 필요가 없습니다.
— Jronny

나는 현장의 많은 교사들과 동의하며 보통 당신이 의미하는 바를 코드화하는 것이 좋습니다. 이 평행을 원한다고 말하는 것은 아무런 이점이 없으며 비밀리에 "어쨌든
— 그것이이

나는 그것을 평행하게 만드는 것이 더 빠르거나 나를 깨달아 준다고 생각합니다. 이것이 내가 이것을 ParallelEnumerable로 변환하는 이유입니다. 그래서 나는 의미하는 바를 말하려고 생각합니다 ... 고마워.
— Jronny
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.