2015-05-17 37 views
0

我使用兩個幾乎相同的(唯一的例外是,一個有.ToDictinct(),而另一個不)調用。是否有可能將它們變成一種我可以在一個地方打電話和更換的方法?使LINQ到字典進入方法體

private void Splitter1(string[] file) 
{    
    tempDict = file 
     .SelectMany(i => File.ReadAllLines(i) 
     .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', '{', '[', '(', '}', ']', ')', 
     '<', '>', '-', '=', '/', '"', ';', ':', '+', '_', '*' }, StringSplitOptions.RemoveEmptyEntries))      
     .AsParallel() 
     .Select(word => word.ToLower()) 
     .Where(word => !StopWords.Contains(word)) 
     .Where(word => !PopulatNetworkWords.Contains(word)) 
     .Where(word => !word.All(char.IsDigit)) 
     .Distinct()) 
     .GroupBy(word => word)      
     .ToDictionary(g => g.Key, g => g.Count()); 
} 
private void Splitter2(string[] file) 
{    
    tempDict = file 
     .SelectMany(i => File.ReadAllLines(i) 
     .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', '{', '[', '(', '}', ']', ')', 
     '<', '>', '-', '=', '/', '"', ';', ':', '+', '_', '*' }, StringSplitOptions.RemoveEmptyEntries)))      
     .AsParallel() 
     .Select(word => word.ToLower()) 
     .Where(word => !StopWords.Contains(word)) 
     .Where(word => !PopulatNetworkWords.Contains(word)) 
     .Where(word => !word.All(char.IsDigit)) 
     .GroupBy(word => word)      
     .ToDictionary(g => g.Key, g => g.Count()); 
} 

回答

2

由於不同兩者之間是與否Distinct()被稱爲它,因爲Distinct()既適用於並返回IEnumerable<T>(或適用於並返回IQueryable<T>,然後首先創建相應的IEnumerable<T>,然後決定是否將其替換爲調用Distinct()的結果,然後繼續:

private void Splitter(string[] file, bool distinct) 
{    
    IEnumerable<string> query = file 
    .SelectMany(i => File.ReadAllLines(i) 
    .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', '{', '[', '(', '}', ']', ')', 
    '<', '>', '-', '=', '/', '"', ';', ':', '+', '_', '*' }, StringSplitOptions.RemoveEmptyEntries))      
    .AsParallel() 
    .Select(word => word.ToLower()) 
    .Where(word => !StopWords.Contains(word)) 
    .Where(word => !PopulatNetworkWords.Contains(word)) 
    .Where(word => !word.All(char.IsDigit)); 
    if(distinct) 
    query = query.Distinct()); 
    return query 
    .GroupBy(word => word)      
    .ToDictionary(g => g.Key, g => g.Count()); 
} 

(順便說一句,你可能會發現新的ReadLines作品比ReadAllLines更好,尤其是對於大型文件。 ReadAllLines立即將所有行讀入內存,而不是在您使用它們時讀取它們,因此會浪費大量內存並延遲處理)。

+0

這將是一個小OT,但更改'ReadAllLines'到'ReadLines'就夠了嗎?或者它需要一些東西(也許它會返回不同類型的數據?)? –

+0

'ReadAllLines'返回'string []'和'ReadLines'返回'IEnumerable ',但是您使用'ReadAllLines'的方式除了實現'IEnumerable '這個事實外,並不依賴於'string []',所以你可以簡單地用'ReadLines'替換'ReadAllLines'。其他的替換可能需要更多的工作(如果它已經通過索引通過數組),或者甚至不值得。 –

+0

ReadAllLines是一個很好的優化 –

1

爲什麼不能是這樣的:

private void Splitter1(string[] file, bool useDistinct = false)) 
    { 
     tempDict = file 
      .SelectMany(i => File.ReadAllLines(i) 
      .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', '{', '[', '(', '}', ']', ')', 
    '<', '>', '-', '=', '/', '"', ';', ':', '+', '_', '*' }, StringSplitOptions.RemoveEmptyEntries)) 
      .AsParallel() 
      .Select(word => word.ToLower()) 
      .Where(word => !StopWords.Contains(word)) 
      .Where(word => !PopulatNetworkWords.Contains(word)) 
      .Where(word => !word.All(char.IsDigit)) 
      .Select(x => useDistinct ? x.Distinct() : x) 
      .GroupBy(word => word) 
      .ToDictionary(g => g.Key, g => g.Count()); 
    } 
+0

這裏如果'useDistinct'是真實的,'Distinct'用,而不是讓「阿爸」,「阿爸」,「ABC」,「ABC」每個項目上調用,而不是查詢,所以,「ABC」你得到「ab」,「abc」,「abc」。 –

+0

@Jon Hanna這是正確的我編輯的代碼,現在應該沒問題 – ferdinand

0

由於LINQ的推遲執行,你可以建立單獨的語句中的條款。

private void Splitter1(string[] file, bool distinct) 
    {    
     var query = file.SelectMany (i => File.ReadAllLines(i) 
       .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', '{', '[', '(', '}', ']', ')', 
       '<', '>', '-', '=', '/', '"', ';', ':', '+', '_', '*' }, StringSplitOptions.RemoveEmptyEntries))      
       .AsParallel() 
       .Select(word => word.ToLower()) 
       .Where(word => !StopWords.Contains(word)) 
       .Where(word => !PopulatNetworkWords.Contains(word)) 
       .Where(word => !word.All(char.IsDigit))); 

     if (distinct) 
     { 
      query = query.Distinct(); 
     } 
     query.GroupBy(word => word)      
       .ToDictionary(g => g.Key, g => g.Count()); 
    } 

我沒有測試此代碼,所以你meay需要調整它。但是,基本思想是,延遲執行允許您根據邏輯改變查詢。

+0

我喜歡這個想法,不得不看看它。 –