Удаление символов из строк с помощью LINQ
Я пытаюсь освежить мой LINQ, написав несколько простых методов расширения. Есть ли лучший способ написать такую функцию, как ниже, которая удаляет данный список символов из строки (используя LINQ)?
Это помогает мне думать о методах расширения, которые LINQ полагается сначала:
public static string Remove(this string s, IEnumerable<char> chars)
{
string removeChars = string.Concat(chars);
return new string(s.ToCharArray().Where(c => !removeChars.Contains(c)).ToArray());
}
Но это довольно уродливо. Ergo LINQ.
Разница, которую я замечаю в инструкции LINQ, заключается в том, что мне нужно использовать "select", тогда как с помощью метода расширения мне не нужно.
/// <summary>Strip characters out of a string.</summary>
/// <param name="chars">The characters to remove.</param>
public static string Remove(this string s, IEnumerable<char> chars)
{
string removeChars = string.Concat(chars);
var stripped = from c in s.ToCharArray()
where !removeChars.Contains(c)
select c;
return new string(stripped.ToArray());
}
Итак, мне интересно, является ли это (последний фрагмент выше) оператором LINQ, чтобы выполнить удаление символов.
Ответы
Ответ 1
Я бы предпочел первую форму с методами расширения, но упрощенную до
public static string Remove(this string s, IEnumerable<char> chars)
{
return new string(s.Where(c => !chars.Contains(c)).ToArray());
}
Что касается ключевого слова выбрать, это обязательно во второй форме. Документация говорит, что "выражение запроса должно заканчиваться либо предложением select, либо предложением группы" . Поэтому я бы избегал синтаксического сахара LINQ.
Ответ 2
попробуйте это для терпения
public static string Remove(this string source, IEnumerable<char> chars) {
return new String(source.Where(x => !chars.Contains(x)).ToArray());
}
ИЗМЕНИТЬ
Обновлено, чтобы исправить удаление дубликатов из источника
Ответ 3
Лично я склонен использовать первый синтаксис для нереляционных ситуаций. Когда мне нужно выполнить реляционные операции (join), скажите с помощью деревьев выражений против SQL, я использую их позже. Но это связано только с тем, что он более читабельен для меня, использующего SQL некоторое время.
Ответ 4
Вы получаете небольшое увеличение производительности при использовании stringBuilder вместо новой строки. Ниже приведены результаты:
StringBuilder 00: 00: 13.9930633
new String 00: 00: 15.1495309
string s = "ababababajjjaazsiajjsoajiojsioajlmmzaaokpdahgffaiojsia";
var sw = new Stopwatch();
sw.Start();
var toRemove = new char[] { 'j', 'a', 'z' };
for (int i = 0; i < 1000000; i++)
{
StringBuilder sb = new StringBuilder(s.Length, s.Length);
foreach (var c in s) if (!toRemove.Contains(c)) sb.Append(c);
}
Console.WriteLine("StringBuilder " + sw.Elapsed);
sw.Restart();
for (int i = 0; i < 1000000; i++)
{
new string(s.Where(c => !toRemove.Contains(c)).ToArray());
}
Console.WriteLine("new String " + sw.Elapsed);