Удаление символов из строк с помощью 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);