2009-11-05 35 views
3

我該如何用一個優雅的LINQ語句替換ConvertListToString(extensions)如何將此12行方法轉換爲單行LINQ表達式?

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

    } 
} 

回答

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

這是比我更好的答案,因爲這會將他更多的原始代碼替換爲Linq,而不僅僅是回答他的確切問題。我的投票在這裏。 – 2009-11-05 12:49:35

+2

錯!這是2行。 – 2009-11-05 12:58:08

+1

請注意,這也是一個很好的例子,說明爲什麼儘快接受答案並不是一個好主意。相反,即使您決定自己希望儘早使用哪個答案,也應該將問題留出一段時間,以查看是否有更好的答案冒泡到頂端。 – 2009-11-05 13:04:14

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",會發生什麼情況,這些將被計爲兩個不同的擴展名。

在致電Distinct之前,應調用ToUpper來解決此問題。

代替原來的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(", "); 
0

如何:

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

這個怎麼樣...

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

這確實是在同一行,我已經感動了「ToUpper的」出到最後的字符串,這樣它對只調用一次。

很明顯,你可以扔掉方法ConvertListToString和內聯,如果你想。

相關問題