如何将这个12行方法转换为1行LINQ表达式?

时间:2009-11-05 12:42:09

标签: c# linq

如何用优雅的LINQ语句替换ConvertListToString(extensions)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestExtn2343
{
    class Program
    {
        public static void Main(string[] args)
        {
            string[] files = { "test.txt", "test2.txt", 
                               "test.as", "notes.doc", 
                               "data.xml", "test.xml", 
                               "test.html", "notes.txt", 
                               "test.xls" };

            List<string> extensions = (from file in files
                             let index = file.LastIndexOf('.') + 1
                             select file.Substring(index)).Distinct().ToList<string>();

            Console.WriteLine("The kinds of file extensions used are {0}.", ConvertListToString(extensions));
            Console.ReadLine();
        }

        public static string ConvertListToString(List<string> list) {
            StringBuilder sb = new StringBuilder();
            int count = 1;
            foreach (var listItem in list)
            {
                sb.Append(listItem.ToUpper());
                if (count != list.Count)
                    sb.Append(", ");
                count++;
            }
            return sb.ToString();
        }

    }
}

4 个答案:

答案 0 :(得分:17)

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

答案 1 :(得分:15)

以下是:

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

注意,我可能不会把它写成一行,而是这样:

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

如果你不介意直接使用Linq扩展方法,而不是Linq查询语法,你可以使用它:

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

另一种变体是在最终字符串上调用ToUpper

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

最后,在.NET 4.0中,String.Join最终直接支持IEnumerable<String>,所以这是可能的:

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

请注意,根据您的问题,这可能会导致重复。考虑如果您的原始文件名列表包含"filename.txt""filename.TXT"会发生什么情况,这些将被视为两个不同的扩展名。

在致电ToUpper之前,应该提前致电Distinct来解决此问题。

而不是原始的Linq表达式+代码,我会重写整个事情:

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

如果将以下实用程序方法添加到代码库中,则可以进一步简化它:

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

然后你的代码看起来像这样:

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

答案 2 :(得分:1)

这个怎么样......

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

这是一行,我把“ToUpper”移到了最后的字符串上,所以只调用一次。

显然,如果你愿意的话,你可以扔掉方法ConvertListToString和inline。

答案 3 :(得分:0)

这个怎么样:

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