Klaus Nji
Klaus Nji

Reputation: 18877

.NET char array comparison

I have the following c# method to get a valid file name out of a proposed name:

public static string GetValidFilename(string fileNameCandidate)
{
    var invalids = System.IO.Path.GetInvalidFileNameChars();
    var _name = fileNameCandidate.ToCharArray();
    var validName = _name.Except(invalids).ToArray();
    return new string(validName);
}

What I expected was the original name with any invalid characters from invalids removed. However, what I get is original name with invalid filename characters and others removed.
For example, if I called the method with "ems:almcc_srr_view" as input parameter, I expected "emsalmcc_srr_view as output. What I get is "emsalc_rviw" as output. What did I miss?

Upvotes: 0

Views: 1382

Answers (4)

LBushkin
LBushkin

Reputation: 131806

Enumerable.Except() produces a "set difference" of two sequence - which means that duplicate characters in the input will be eliminated as well.

What you want is:

 _name.Where( x => !invalids.Contains(x) ).ToArray();

Since System.String is IEnumerable<char>, you can simplify this to:

var name = fileNameCandidate.Where( x => !invalids.Contains(x) ).ToArray() );
return new string( name );

Upvotes: 5

LukeH
LukeH

Reputation: 269658

Try this instead:

return new string(fileNameCandidate.Where(c => !invalids.Contains(c)).ToArray());

Upvotes: 0

El Ronnoco
El Ronnoco

Reputation: 11912

Obviously something is going wrong as one 'c' has been removed and not the other! I'd look at this solution.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1503964

You missed the fact that Except is a set operation. In other words, it yields a sequence which doesn't contain any duplicates. (Admittedly the documentation could be a lot clearer on this point.)

You want:

var validName = _name.Where(c => !invalids.Contains(c)).ToArray();

Note that you don't need to call _name.ToCharArray() as string already implements IEnumerable<char>. In other words, you can use:

public static string GetValidFilename(string fileNameCandidate)
{
    var invalids = Path.GetInvalidFileNameChars();
    var validName = fileNameCandidate.Where(c => !invalids.Contains(c))
                                     .ToArray();
    return new string(validName);
}

Upvotes: 4

Related Questions