2009-08-24 12 views
56

वहाँ ऐसा करने का एक बेहतर तरीका है ...सी # में एकाधिक स्ट्रिंग तत्वों की जगह

MyString.Trim().Replace("&", "and").Replace(",", "").Replace(" ", " ") 
     .Replace(" ", "-").Replace("'", "").Replace("/", "").ToLower(); 

मैं एक ही काम करने के लिए इसे कम रखने के लिए स्ट्रिंग वर्ग बढ़ाया लेकिन वहाँ एक तेज तरीका है है?

public static class StringExtension 
{ 
    public static string clean(this string s) 
    { 
     return s.Replace("&", "and").Replace(",", "").Replace(" ", " ") 
       .Replace(" ", "-").Replace("'", "").Replace(".", "") 
       .Replace("eacute;", "é").ToLower(); 
    } 
} 

बस मस्ती के लिए मैं नीचे विभिन्न उदाहरणों बेंचमार्किंग एक सार अप shoved है (और टिप्पणियों में बहस को रोकने के लिए)।

https://gist.github.com/ChrisMcKee/5937656

regex विकल्प स्कोर बहुत; शब्दकोश विकल्प सबसे तेज़ आता है; स्ट्रिंगबिल्डर प्रतिस्थापन का लंबा घुमावदार संस्करण छोटा हाथ से थोड़ा तेज़ है।

+0

यह शब्दकोश संस्करण की तरह लग रहा है कि आप अपने मानक में है के आधार पर प्रतिस्थापन जो मुझे लगता है है के सभी नहीं कर रहा है कि क्या यह तेजी से कर रही है स्ट्रिंगबिल्डर समाधान। 200 9 से – toad

+1

@ टोड हाय; मैंने उस चमकदार गलती के बारे में अप्रैल में नीचे एक टिप्पणी जोड़ा। गीस्ट अपडेट किया गया है हालांकि मैं डी पर छोड़ दिया। शब्दकोश संस्करण अभी भी तेज है। –

+0

संभावित स्ट्रिंग के वैकल्पिक डुप्लिकेट। एकाधिक बार बदलें?] (Http://stackoverflow.com/questions/12007358/alternative-to-string-replace-multiple-times) –

उत्तर

79

तेज - नहीं। अधिक प्रभावी - हाँ, यदि आप StringBuilder कक्षा का उपयोग करेंगे। आपके कार्यान्वयन के साथ प्रत्येक ऑपरेशन एक स्ट्रिंग की एक प्रति उत्पन्न करता है जो परिस्थितियों में प्रदर्शन को खराब कर सकता है। स्ट्रिंग्स अपरिवर्तनीय ऑब्जेक्ट्स हैं इसलिए प्रत्येक ऑपरेशन केवल एक संशोधित प्रतिलिपि देता है।

यदि आप इस विधि को सक्रिय रूप से Strings पर सक्रिय रूप से बुलाए जाने की अपेक्षा करते हैं, तो इसके कार्यान्वयन को StringBuilder कक्षा पर "माइग्रेट" करना बेहतर हो सकता है। इसके साथ किसी भी संशोधन को सीधे उस उदाहरण पर किया जाता है, इसलिए आप अनावश्यक प्रतिलिपि संचालन को छोड़ देते हैं।

public static class StringExtension 
{ 
    public static string clean(this string s) 
    { 
     return new StringBuilder(s) 
       .Replace("&", "and") 
       .Replace(",", "") 
       .Replace(" ", " ") 
       .Replace(" ", "-") 
       .Replace("'", "") 
       .Replace(".", "") 
       .Replace("eacute;", "é") 
       .ToString() 
       .ToLower(); 
    } 
} 
+1

स्पष्टता के लिए शब्दकोश का जवाब सबसे तेज़ है http://stackoverflow.com/a/1321366/52912 –

+2

https://gist.github.com/ChrisMcKee/5937656 पर अपने बेंचमार्क में शब्दकोश परीक्षण पूरा नहीं हुआ है: यह सभी प्रतिस्थापन नहीं करता है और "" प्रतिस्थापित करता है "" नहीं, ""। सभी प्रतिस्थापन नहीं कर सकते कारण कारण हो सकता है, यह बेंचमार्क में सबसे तेज़ क्यों है। रेगेक्स प्रतिस्थापन पूर्ण नहीं है, या तो। लेकिन सबसे महत्वपूर्ण बात यह है कि आपकी स्ट्रिंग टेस्टडाटा _very_ छोटी है। स्वीकार्य उत्तर राज्यों की तरह, स्ट्रिंगबिल्डर के लाभ के लिए स्ट्रिंग को महत्वपूर्ण लंबाई होना चाहिए। क्या आप 10kb, 100kb और 1MB के तारों के साथ बेंचमार्क दोहरा सकते हैं? – Leif

+0

यह एक अच्छा मुद्दा है; क्योंकि यह खड़ा है कि इसका उपयोग यूआरएल सफाई के लिए किया जा रहा था, इसलिए 100kb - 1mb पर परीक्षणों को अवास्तविक माना जाएगा। मैं बेंचमार्क अपडेट करूँगा, इसलिए यह पूरी चीज का उपयोग कर रहा है, यह एक गलती थी। –

8

इस और अधिक कुशल हो जाएगा?

public static class StringExtension { 

     private static Dictionary<string, string> _replacements = new Dictionary<string, string>(); 

     static StringExtension() { 
      _replacements["&"] = "and"; 
      _replacements[","] = ""; 
      _replacements[" "] = " "; 
      // etc... 
     } 

     public static string clean(this string s) { 
      foreach (string to_replace in _replacements.Keys) { 
       s = s.Replace(to_replace, _replacements[to_replace]); 
      } 
      return s; 
     } 
    } 

इसके अलावा StringBuilder के बारे में टाउन के सुझाव में नए जोड़ने ...

+0

पढ़ने के लिए वास्तव में मुश्किल है। मुझे यकीन है कि आप जानते हैं कि यह क्या करता है लेकिन एक जूनियर देव वास्तव में क्या चल रहा है उसके सिर खरोंच करेगा। मैं सहमत हूं- मैं हमेशा कुछ लिखने के लिए हाथों की तलाश भी करता हूं- लेकिन यह केवल मेरी संतुष्टि के लिए था। अन्य लोग गंदगी के ढेर पर बाहर निकल रहे थे। – ppumkin

+2

यह वास्तव में धीमा है। BenchmarkOverhead ... 13ms StringClean-user151323 ... 2843ms StringClean-TheVillageIdiot ... 2921ms दोहराए पर भिन्न लेकिन इस सवाल का जवाब अधिक जीतता https://gist.github.com/anonymous/5937596 –

10

हो सकता है कि एक छोटे से अधिक पठनीय:

public static class StringExtention 
{ 
    public static string clean(this string s) 
    { 
     StringBuilder sb = new StringBuilder (s); 

     sb.Replace("&", "and"); 
     sb.Replace(",", ""); 
     sb.Replace(" ", " "); 
     sb.Replace(" ", "-"); 
     sb.Replace("'", ""); 
     sb.Replace(".", ""); 
     sb.Replace("eacute;", "é"); 

     return sb.ToString().ToLower(); 
    } 
} 
+4

यह होगा इस तरह पठनीय: 'निजी स्थिर शब्दकोश <स्ट्रिंग, स्ट्रिंग> _replacements = नया शब्दकोश () {{" & "," और "}, {", "," "}, {" "," " }/* आदि * /}; – ANeves

+1

या निश्चित रूप से ... निजी स्थैतिक रीडोनली शब्दकोश <स्ट्रिंग, स्ट्रिंग> प्रतिस्थापन = नया शब्दकोश () {{"&", "और"}, { ",", "" }, { " ", " " } /* आदि */ }; \t \t सार्वजनिक स्थैतिक स्ट्रिंग स्वच्छ (इस स्ट्रिंग रों) \t \t { \t \t \t वापसी Replacements.Keys.Aggregate (रों, (वर्तमान, toReplace) => current.Replace (toReplace, प्रतिस्थापन [toReplace])); \t \t} –

1

मैं ऐसी ही कुछ कर रहा हूँ, लेकिन मेरे मामले में मैं क्रमबद्धता/डी-क्रमबद्धता कर रहा हूँ तो मैं जाने के लिए सक्षम होना चाहिए दोनों दिशाओं में। मुझे एक स्ट्रिंग का उपयोग करना पड़ता है [] [] प्रारंभिक समेत शब्दकोश के लगभग समान रूप से काम करता है, लेकिन आप दूसरी दिशा भी जा सकते हैं, विकल्प को अपने मूल मूल्यों पर वापस कर सकते हैं, जो कुछ भी वास्तव में करने के लिए सेट नहीं किया गया है।

संपादित करें: आप क्रम में Dictionary<Key,List<Values>> उपयोग कर सकते हैं स्ट्रिंग के रूप में एक ही परिणाम प्राप्त करने के लिए [] []

4

आप एक सुंदर समाधान के बाद बस कर रहे हैं और कुछ नैनोसेकंड को बचाने की जरूरत नहीं है, तो कैसे कुछ LINQ चीनी के बारे में ?

var input = "test1test2test3"; 
var replacements = new Dictionary<string, string> { { "1", "*" }, { "2", "_" }, { "3", "&" } }; 

var output = replacements.Aggregate(input, (current, replacement) => current.Replace(replacement.Key, replacement.Value)); 
+0

सार में उदाहरण के लिए C के समान (यदि आप इसे ऊपर देखो भद्दा LINQ बयान टिप्पणी में है) –

+1

दिलचस्प है कि आप के रूप में "भद्दा" एक प्रक्रियात्मक की तुलना में एक कार्यात्मक बयान परिभाषित करते हैं। – TimS

+0

इसके बारे में बहस नहीं करेगा; इसकी केवल वरीयता है। जैसा कि आप कहते हैं, linq बस वाक्य रचनात्मक चीनी है; और जैसा कि मैंने कहा था कि मैं पहले ही कोड के समतुल्य समकक्ष रखूंगा :) –

3

एक ऐसी चीज है जिसे सुझाए गए समाधानों में अनुकूलित किया जा सकता है। Replace() पर कई कॉल करने के लिए कोड एक ही स्ट्रिंग पर एकाधिक पास करने के लिए बनाता है। बहुत लंबे तारों के साथ समाधान सीपीयू कैश क्षमता याद आती है क्योंकि समाधान धीमा हो सकता है। किसी को replacing multiple strings in a single pass पर विचार करना चाहिए।

-1
string input = "it's worth a lot of money, if you can find a buyer."; 
for (dynamic i = 0, repl = new string[,] { { "'", "''" }, { "money", "$" }, { "find", "locate" } }; i < repl.Length/2; i++) { 
    input = input.Replace(repl[i, 0], repl[i, 1]); 
} 
+1

आपको अपने उत्तरों में संदर्भ जोड़ने पर विचार करना चाहिए। यह क्या कर रहा है इसके बारे में एक संक्षिप्त स्पष्टीकरण की तरह और, यदि प्रासंगिक है, तो आपने इसे किस तरह लिखा है। – Neil

1

एक अन्य विकल्प LINQ का उपयोग कर

[TestMethod] 
public void Test() 
{ 
    var input = "it's worth a lot of money, if you can find a buyer."; 
    var expected = "its worth a lot of money if you can find a buyer"; 
    var removeList = new string[] { ".", ",", "'" }; 
    var result = input; 

    removeList.ToList().ForEach(o => result = result.Replace(o, string.Empty)); 

    Assert.AreEqual(expected, result); 
} 
+0

आप 'var removeList = new list {/*...*/} घोषित कर सकते हैं;' फिर बस 'removeList.ForEach (/*...*/);' को कॉल करें और अपने कोड को सरल बनाएं। ध्यान दें कि यह पूरी तरह से प्रश्न का उत्तर नहीं देता है क्योंकि * सभी * पाए गए तारों को 'स्ट्रिंग.एक्टी' के साथ बदल दिया गया है। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^