score:17

Accepted answer
var s = string.Join(", ", files.Select(file => Path.GetExtension(file))
    .Distinct(StringComparer.InvariantCultureIgnoreCase).ToArray());

score:15

Here's how:

String s = String.Join(", ", (from extension in extensions select extension.ToUpper()).ToArray());

Note, I would probably not write this as one line, rather like this:

String s = String.Join(", ",
    (from extension in extensions
     select extension.ToUpper()).ToArray());

If you don't mind just going for the Linq extension methods directly, instead of the Linq query syntax, you can use this:

String s = String.Join(", ", extensions.Select(e => e.ToUpper()).ToArray());

Another variant would be to just call ToUpper on the final string instead:

String s = String.Join(", ", extensions.ToArray()).ToUpper();

And finally, in .NET 4.0, String.Join finally supports IEnumerable<String> directly, so this is possible:

String s = String.Join(", ", extensions).ToUpper();

Note that per your question, this might lead to duplicates nonetheless. Consider what would happen if your original list of filenames contained both "filename.txt" and "filename.TXT", these would be counted as two distinct extensions.

The call to ToUpper should be moved up before the call to Distinct to fix this.

Instead of the original Linq expression + code, I would rewrite the whole thing to this:

String[] distinctExtensions = files
    .Select(fileName => Path.GetExtension(fileName).ToUpper())
    .Distinct()
    .ToArray();
String distinctExtensionsAsString = String.Join(", ", distinctExtensions);

If you add the following utility method to your code library, you can simplify it further:

public static class StringExtensions
{
    public static String Join(this IEnumerable<String> elements, String separator)
    {
        if (elements is String[])
            return String.Join(separator, (String[])elements);
        else
            return String.Join(separator, elements.ToArray());
    }
}

and then your code can look like this:

String distinctExtensionsAsString = files
    .Select(fileName => Path.GetExtension(fileName).ToUpper())
    .Distinct()
    .Join(", ");

score:0

How about this:

String output = String.Join(", ",(from file in files
  let index = file.LastIndexOf('.') + 1
  select file.Substring(index)).Distinct().ToArray<string>());

score:1

How about this...

public static string ConvertListToString(List<string> list) 
{ 
    return list.Aggregate((x, y) => x + ", " + y).ToUpper();
}

This does it in one line, and I've moved the "ToUpper" out onto the final string so it's only called once.

Clearly you could then throw away the method ConvertListToString and inline if you wanted.


Related Articles