tags:

views:

618

answers:

5

I'm trying to brush up on my LINQ by writing some simple extension methods. Is there any better way to write such a function as below that removes a given list of characters from a string (using LINQ)?

It helps me to think of the extension methods that LINQ relies on first:

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());
}

But that's pretty ugly. Ergo LINQ.

The difference that I notice in the LINQ statement is that I have to use 'select' whereas with the extension method, I don't have to.

/// <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());
}

So I'm wondering if this (last snippet above) is the tersest LINQ statement to accomplish removal of characters.

+1  A: 

try this for terseness

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

EDIT

Updated to correct it removing duplicates from source

JaredPar
Unfortunately this will remove all duplicates from source even if they are not in chars. For example, if source == "abcabc" and chars == "a" only "bc" will be returned instead of "bcbc".
Alexander Prokofyev
@Alexander, Thanks for pointing that out. I forgot Except had that behavior
JaredPar
+4  A: 

I would prefer the first form with extension methods though simplified to

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

As for select keyword, it's obligatory in second form. The documentation says what "A query expression must terminate with either a select clause or a group clause". That's why I would avoid LINQ syntactic sugar.

Alexander Prokofyev
A: 

Though not quite terse but interesting

public static string Filter(this string source, params char[] chars)
{
    var filtered = source.Where(source.Except(chars).Contains);
    return new String(filtered.ToArray());
}
Hasan Khan
The same error as @JaredPar did. You can't use Enumerable.Except here. Read comments to his answer - http://stackoverflow.com/questions/449513/removing-characters-from-strings-with-linq#449577
Alexander Prokofyev
Dude this piece of code has been tested and it works and it is not the same as the one you've mentioned.
Hasan Khan
A: 
string result = new string (s.Except(chars).ToArray());
David B
+1  A: 

Personally I tend to use the first syntax for non relational situations. When I need to perform relational operations (join), say with Expression Trees against SQL i use the later. But, this is only because its more readable for me having used SQL for a while.

ccook