Есть ли лучший способ сделать это ...
MyString.Trim().Replace("&", "and").Replace(",", "").Replace(" ", " ")
.Replace(" ", "-").Replace("'", "").Replace("/", "").ToLower();
Я расширил класс String, чтобы сократить его до одной задачи, но есть ли более быстрый способ?
public static class StringExtension
{
public static string clean(this string s)
{
return s.Replace("&", "and").Replace(",", "").Replace(" ", " ")
.Replace(" ", "-").Replace("'", "").Replace(".", "")
.Replace("eacute;", "é").ToLower();
}
}
Просто для удовольствия (и чтобы остановить аргументы в комментариях) я поднял суть, сравнивая различные примеры ниже.
Опция регулярного выражения очень популярна; вариант со словарем подходит быстрее всего; длинная версия замены струнного конструктора немного быстрее, чем короткая.
c#
string
refactoring
immutability
Крис Макки
источник
источник
Ответы:
Быстрее - нет. Эффективнее - да, если вы воспользуетесь
StringBuilder
классом. В вашей реализации каждая операция генерирует копию строки, которая при определенных обстоятельствах может снизить производительность. Строки - это неизменяемые объекты, поэтому каждая операция просто возвращает измененную копию.Если вы ожидаете, что этот метод будет активно вызываться для кратных
Strings
значительных длин, может быть лучше «перенести» его реализацию вStringBuilder
класс. С его помощью любая модификация выполняется непосредственно в этом экземпляре, поэтому вы избавляетесь от ненужных операций копирования.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(); } }
источник
это будет более эффективно:
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(); } }
источник
Если вам просто нужно красивое решение и вам не нужно экономить несколько наносекунд, как насчет сахара 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));
источник
Может чуть читабельнее?
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; } }
Также добавьте предложение New In Town о StringBuilder ...
источник
private static Dictionary<string, string> _replacements = new Dictionary<string, string>() { {"&", "and"}, {",", ""}, {" ", " "} /* etc */ };
List<Tuple<string,string>>
. Это также изменяет порядок выполнения замен, И не так быстро, как, напримерs.Replace("a").Replace("b").Replace("c")
. Не используйте это!Есть одна вещь, которую можно оптимизировать в предлагаемых решениях. Наличие множества вызовов в
Replace()
заставляет код выполнять несколько проходов по одной и той же строке. С очень длинными строками решения могут работать медленно из-за нехватки емкости кэша ЦП. Может быть, стоит подумать о замене нескольких строк за один проход .источник
Другой вариант использования 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); }
источник
var removeList = new List<string> { /*...*/ };
затем просто позвонитеremoveList.ForEach( /*...*/ );
и упростите свой код. Также обратите внимание, что он не полностью отвечает на вопрос, потому что все найденные строки заменяются наString.Empty
.Я делаю нечто подобное, но в моем случае я выполняю сериализацию / десериализацию, поэтому мне нужно иметь возможность идти в обоих направлениях. Я считаю, что использование строки [] [] работает почти идентично словарю, включая инициализацию, но вы можете пойти и в другом направлении, возвращая заменители к их исходным значениям, для чего словарь действительно не настроен.
Изменить: вы можете использовать
Dictionary<Key,List<Values>>
для получения того же результата, что и строка [] []источник
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]); }
источник