Удаление символов из строк с помощью LINQ - PullRequest
12 голосов
/ 16 января 2009

Я пытаюсь освежить свой 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 для выполнения удаления символов.

Ответы [ 4 ]

12 голосов
/ 16 января 2009

Я бы предпочел первую форму с методами расширения, хотя и упрощенной до

public static string Remove(this string s, IEnumerable<char> chars)
{
    return new string(s.Where(c => !chars.Contains(c)).ToArray());
}

Что касается выберите ключевое слово , оно обязательно во второй форме. В документации говорится, что «выражение запроса должно заканчиваться либо предложением select, либо предложением group». Вот почему я бы избегал синтаксического сахара LINQ.

1 голос
/ 16 января 2009

Лично я склонен использовать первый синтаксис для нереляционных ситуаций. Когда мне нужно выполнить реляционные операции (соединение), скажем, с деревьями выражений против SQL, я использую позже. Но это только потому, что мне удобнее читать SQL некоторое время.

1 голос
/ 16 января 2009

попробуйте это для краткости

public static string Remove(this string source, IEnumerable<char> chars) {
  return new String(source.Where(x => !chars.Contains(x)).ToArray());
}

EDIT

Обновлено, чтобы исправить это, удалив дубликаты из источника

0 голосов
/ 13 января 2012

Вы получаете небольшое повышение производительности при использовании stringBuilder вместо новой строки. Ниже приведены результаты:

StringBuilder 00: 00: 13.9930633 новая строка 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...