Gibt es einen besseren Weg, dies zu tun ...
MyString.Trim().Replace("&", "and").Replace(",", "").Replace(" ", " ")
.Replace(" ", "-").Replace("'", "").Replace("/", "").ToLower();
Ich habe die String-Klasse erweitert, um sie auf einen Job zu beschränken, aber gibt es einen schnelleren Weg?
public static class StringExtension
{
public static string clean(this string s)
{
return s.Replace("&", "and").Replace(",", "").Replace(" ", " ")
.Replace(" ", "-").Replace("'", "").Replace(".", "")
.Replace("eacute;", "é").ToLower();
}
}
Nur zum Spaß (und um die Argumente in den Kommentaren zu stoppen) habe ich die verschiedenen Beispiele unten auf den Punkt gebracht.
Die Regex-Option punktet furchtbar. Die Wörterbuchoption wird am schnellsten angezeigt. Die langatmige Version des Stringbuilder-Ersatzes ist etwas schneller als die kurze Hand.
c#
string
refactoring
immutability
Chris McKee
quelle
quelle
Antworten:
Schneller - nein. Effektiver - ja, wenn Sie die
StringBuilder
Klasse verwenden. Bei Ihrer Implementierung generiert jede Operation eine Kopie einer Zeichenfolge, die unter Umständen die Leistung beeinträchtigen kann. Zeichenfolgen sind unveränderliche Objekte, sodass jede Operation nur eine geänderte Kopie zurückgibt.Wenn Sie erwarten, dass diese Methode für mehrere
Strings
von erheblicher Länge aktiv aufgerufen wird , ist es möglicherweise besser, ihre Implementierung auf dieStringBuilder
Klasse zu "migrieren" . Damit wird jede Änderung direkt an dieser Instanz durchgeführt, sodass Sie unnötige Kopiervorgänge vermeiden.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(); } }
quelle
das wird effizienter:
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(); } }
quelle
Vielleicht etwas lesbarer?
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; } }
Fügen Sie auch den Vorschlag von New In Town zu StringBuilder hinzu ...
quelle
private static Dictionary<string, string> _replacements = new Dictionary<string, string>() { {"&", "and"}, {",", ""}, {" ", " "} /* etc */ };
List<Tuple<string,string>>
. Dies ändert auch die Reihenfolge der Ersetzungen und ist nicht so schnell wie zs.Replace("a").Replace("b").Replace("c")
. Benutze das nicht!Wenn Sie einfach nach einer hübschen Lösung suchen und nicht ein paar Nanosekunden sparen müssen, wie wäre es dann mit etwas LINQ-Zucker?
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));
quelle
Es gibt eine Sache, die in den vorgeschlagenen Lösungen optimiert werden kann. Wenn Sie viele Aufrufe an haben,
Replace()
führt der Code mehrere Durchgänge über dieselbe Zeichenfolge aus. Bei sehr langen Zeichenfolgen können die Lösungen aufgrund fehlender CPU-Cache-Kapazität langsam sein. Möglicherweise sollte man in Betracht ziehen , mehrere Zeichenfolgen in einem einzigen Durchgang zu ersetzen .quelle
Eine andere Option mit linq ist
[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); }
quelle
var removeList = new List<string> { /*...*/ };
dann einfachremoveList.ForEach( /*...*/ );
Ihren Code aufrufen und vereinfachen. Beachten Sie auch, dass die Frage nicht vollständig beantwortet wird, da alle gefundenen Zeichenfolgen durch ersetzt werdenString.Empty
.Ich mache etwas Ähnliches, aber in meinem Fall mache ich Serialisierung / De-Serialisierung, also muss ich in beide Richtungen gehen können. Ich finde, dass die Verwendung eines Strings [] [] fast identisch mit dem Wörterbuch funktioniert, einschließlich der Initialisierung, aber Sie können auch in die andere Richtung gehen und die Substitute auf ihre ursprünglichen Werte zurücksetzen, etwas, für das das Wörterbuch wirklich nicht eingerichtet ist.
Bearbeiten: Sie können verwenden
Dictionary<Key,List<Values>>
, um das gleiche Ergebnis wie Zeichenfolge [] [] zu erhalten.quelle
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]); }
quelle