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.