क्या मैं एक तार को (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
मुझे नहीं लगता कि यह सुरुचिपूर्ण है। अजगर में ऐसा करने के लिए कोड है: स्निप * गुणक (यह भयानक नहीं है .. लेकिन न तो यह सुंदर है)।
हेजहोग

7
@deantedhedgehog मुझे पता है कि आप अपने स्वयं के मनोभ्रंश को स्वीकार करते हैं, लेकिन यहां तक ​​कि जैसा कि आप करते हैं, वैसे ही आप यह देख सकते हैं कि पायथन उदाहरण ने C # प्रश्न का बहुत अच्छा उत्तर नहीं दिया होगा ... मुझे लगता है कि हम में से अधिकांश देख सकते हैं उस भाषा का चयन हमेशा एक समझौता है, और किसी भी सवाल का बहुत ज्यादा जवाब वकालत के साथ या तो खिलाफ या खिलाफ दिया जा सकता है।
विल डीन

1
@ डब्लू डीन: मैं मैथ्यू निकोल्स के बयान का जिक्र कर रहा था जो आपके पास मौजूद कोड की शान के बारे में है। जहां तक ​​मैं बता सकता हूं कि आपका कोड C # के लिए सुरुचिपूर्ण है, क्योंकि यह वर्तमान में इस समस्या के लिए खड़ा है। वह बिंदु जो मैं बनाने की कोशिश कर रहा हूं: (मुझे विश्वास है) यह बहुत आसान होगा (Microsoft के लिए, जैसा कि स्ट्रिंग्स को सील किया गया है) सी # का विस्तार करने के लिए int * string गुणा करने के लिए * ऑपरेटर को ओवरलोड करने के लिए। जो तब वास्तव में कुछ सार्वभौमिक अर्थों में सुरुचिपूर्ण होगा, इहो, सी # द्वारा लगाए गए बाधाओं के संदर्भ में केवल सुरुचिपूर्ण नहीं है क्योंकि यह वर्तमान में मौजूद है।
हेजहोग

@deantedhedgehog मेरे लिए, जो कि द्विआधारी का operator*प्रतिनिधित्व करता है के खिलाफ जाता है । मुझे लगता है अपने हरेक व्यक्ति के लिए।
TEK

99

ध्यान दें कि यदि आपका "स्ट्रिंग" केवल एक एकल वर्ण है, तो इसे संभालने के लिए स्ट्रिंग निर्माता का अधिभार है:

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

यह वास्तव में समर्थक है।
ज़ेवेन ज़ार्यान

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 में गुणक source.Length का उपयोग करके अनुकूलन
मार्क Gravell

2
मार्क की टिप्पणी सिर्फ मैं कहाँ जा रहा था :)
जॉन स्कीट

1
आप (source.Length * गुणक) ही नहीं, (गुणक) की जरूरत है
मार्क Gravell

1
बहुत यकीन। यह दृश्यों के पीछे एक स्ट्रिंग (उस लंबाई की) को आवंटित करता है, फिर इसे म्यूट करता है। यह होता है आदि एक नियमित रूप से सूची <टी> की तरह काम नहीं
मार्क Gravell

1
विस्तार विधि यहाँ आदर्श है।
क्रिस बैलेंस

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

मुझे लगता है कि मैंने कुछ समय पहले स्टैक ओवरफ्लो से एक को खींच लिया था, इसलिए यह मेरा विचार नहीं है।


9

आपको एक विधि लिखनी होगी - बेशक, सी # 3.0 के साथ यह एक विस्तार विधि हो सकती है:

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

फिर:

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

.NET3 में भी Enumerable.Repeat नहीं था?
विल डीन

@Will - .NET 3 WCF / WPF आदि था, इसलिए नहीं; यह .NET 3.5 में मौजूद है, लेकिन फिर आपको इसकी आवश्यकता string.Joinभी होगी - क्यों न केवल एन बार लूप किया जाए? बहुत अधिक प्रत्यक्ष।
मार्क Gravell

धन्यवाद - मैं 3.0 बनाम 3.5 के बारे में ठीक से नहीं सोच रहा था। के रूप में क्यों नहीं बस एक पाश का उपयोग करें, निश्चित रूप से कार्यात्मक बनाम अनिवार्य बहस का पूरा सार है? मैंने एक .net 4 उत्तर को नीचे पोस्ट किया है जो मुझे लगता है कि 'कार्यात्मक चतुराई' बनाम 'लूपिंग स्पष्टता' बहस में बहुत बुरा नहीं है।
डीन

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

यदि आपके पास .net 3.5 है, लेकिन 4.0 नहीं है, तो आप System.Linq का उपयोग कर सकते हैं

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

एक स्ट्रिंग प्राप्त करने के लिए आपको अभी भी आवश्यकता होगी String.Concat, और 3.5 पर आपको भी आवश्यकता होगी .ToArray()। सबसे सुरुचिपूर्ण समाधान नहीं, मुझे डर है।
कोबी

2

चूंकि हर कोई अपने स्वयं के .NET4 / Linq उदाहरण जोड़ रहा है, इसलिए मैं अपना स्वयं का भी जोड़ सकता हूं। (मूल रूप से, यह DrJokepu की, एक लाइनर के लिए कम)

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तत्वों को क्रम में उपयोग करने की आवश्यकता होती है, इसलिए उनकी पीढ़ी को समानांतर करना अनसुना है।
गाबे

@ गैब: चूंकि आइटम समान हैं और वास्तव में इस स्ट्रीपिंग की प्रतियां हैं, इसलिए यहां ऑर्डर देने के बारे में चिंता करने की कोई आवश्यकता नहीं है, मुझे लगता है।
जॉनी

मैं इस क्षेत्र के कई शिक्षकों से सहमत हूं कि आमतौर पर यह कहने के लिए कोड के लिए अच्छा है कि आपका क्या मतलब है। यह कहने का कोई लाभ नहीं है कि आप इस समानांतर चाहते हैं और केवल चुपके से सोचते हैं "ठीक है, मुझे पता है कि यह इस विशेष मामले में समानांतर नहीं होगा"
sehe

मुझे लगता है कि इसे समानांतर बनाने से यह तेज हो जाता है, या कृपया मुझे बताएं। इसलिए मैं इसे ParallelEnumerable में परिवर्तित कर रहा हूं, इस प्रकार मुझे लगता है कि मुझे यह कहने के लिए कोड चाहिए कि मेरा क्या मतलब है ... धन्यवाद।
Jronny
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.