2010-07-16 28 views
0

我在控制檯應用程序中再現了我的問題。以下是代碼。C#中的Linq查詢無法按預期工作

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

namespace LinqSample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string query = "Maine, Maryland, Massachusetts, M"; 

      var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries); 
      string lastQuery = queries[queries.Length - 1].Trim(); 

      if (queries.Length > 1) 
      { 
       var remQueries = queries.Take(queries.Length - 1).ToArray(); 

       string[] suggestions = new string[] {"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", 
      "Mississippi", "Missouri", "Montana"}; 

       System.Console.WriteLine("Before Except "); 

       suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); }); 

       var unqiueSugs = from sug in suggestions 
           where !remQueries.Any(q => q.Equals(sug, StringComparison.OrdinalIgnoreCase)) 
           select sug; 

       if (unqiueSugs != null) 
       { 
        suggestions = unqiueSugs.ToArray(); 
       } 

       System.Console.WriteLine("\n After Except "); 
       suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); }); 
      } 
     } 
    } 
} 

上面的代碼後,我除了建議包含除「緬因」,「馬里蘭」,「馬薩諸塞州」的所有值。但它有7個值包括「馬里蘭州」,「馬薩諸塞州」。我在哪裏做錯了?請幫助。

編輯: 我使用開發工作室2008與.NET 3.5 sp1。我使用上面的代碼在asp.net mvc的

+0

'uniqueSugs'永遠不會爲空。但是,它可以是空的。 – Marc 2010-07-16 13:33:32

+0

正如@Matthew Flaschen所說,這段代碼看起來工作正常 – 2010-07-16 13:42:59

+5

提供一個實際編譯和運行的小*完整*示例,用於演示您遇到的問題。這有兩個目的:首先,當它帶有錯誤的代碼是你所呈現的代碼時,它使我們更容易理解問題。其次,這樣做*你可能會發現你的bug *。 – 2010-07-16 13:45:53

回答

9

上面的代碼後,我只是建議,除包含所有值....

那麼,這個怎麼樣:

var unqiueSugs = suggestions.Except(remQueries, StringComparer.OrdinalIgnoreCase)); 

沒有必要讓你的生活更加複雜不必要

編輯:添加StringComparer.OrdinalIgnoreCase完整性

編輯:正如我所說,你有一個空白問題。快來看看remQueries仔細一看,有前導空格,如「馬里蘭」,而不是「馬里蘭」

只需使用

suggestions = suggestions.Select(s => s.Trim()).Except(remQueries.Select(s => s.Trim()), StringComparer.OrdinalIgnoreCase).ToArray(); 

,你會沒事的。

string query = "Maine, Maryland, Massachusetts, M"; 
var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries); 

會給你這些字符串: 「緬因」, 「美林」, 「馬薩諸塞州」, 「M」

+0

答案很清晰。我試過這個,但它也不起作用。如果我檢查之前除了方法執行,我看到建議有8和remQueries有3個值。執行完成後,unqiueSugs包含7個值。現在我真的很困惑。 – mohang 2010-07-16 13:40:58

+0

不,它不是。我的解決方案正常工作,正如馬修的做法。你的問題必須在其他地方。正如Eric Lippert所建議的,提供一個完整的代碼示例。你確定沒有錯別字嗎?也許是前/後空白?然後嘗試類似suggestions.Select(s => s.Trim())。除(remQueries.Select(s => s.Trim()),StringComparer.OrdinalIgnoreCase)); – sloth 2010-07-16 13:54:26

1

作品的我的操作方法對我來說:

var remQueries = new[]{"Maine", "Maryland", "Massachusetts"}; 
var suggestions = new[]{"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana"}; 
var unqiueSugs = from sug in suggestions 
       where ! remQueries.Any(q => q.Equals(sug, StringComparison.OrdinalIgnoreCase)) 
       select sug; 
unqiueSugs; 
{ "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana" } 

您的問題是在其他地方。另請注意,如果您的真實名單較大,您可能會更快地找到Except(使用自定義IEqualityComparer)。

+0

我也是。我使用'string [] suggestions = {...}'作爲我的聲明。 – ChrisF 2010-07-16 13:23:21

1

如何

var unqiueSugs = suggestions.Except(remQueries).ToArray(); 
0

只是在你的代碼快速觀察但貼:

 string query = "Maine, Maryland, Massachusetts, M"; 
     var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries); 

向你4串但你會在我的調試預計徘徊在查詢就是他們不剪裁怎麼樣了: 「緬因」 「馬里蘭」 「馬薩諸塞州」 「M」

(最後3串前注意空間)

我相信下面的代碼是你是什麼後您的修剪操作:

var queries = query.Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries).Select(X => X.Trim()).ToArray(); 
6

那麼,我沒有真正運行這個,但讓我們看看代碼,看看它做了什麼。

 string query = "Maine, Maryland, Massachusetts, M"; 

     var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries); 

query.Trim()什麼也不做,因爲修剪從字符串的開頭和結尾刪除空格,而不是從字符串中間。

該分割生成一個{「緬因州」,「馬里蘭州」,「馬薩諸塞州」,「M」}的數組,分配給查詢。

請注意馬里蘭州和馬薩諸塞州的領先空間。你還沒有剝離這些空間。這似乎是錯誤的。

 string lastQuery = queries[queries.Length - 1].Trim(); 

lastQuery現在是「M」。數組查詢保持不變。

「lastQuery」不會被使用。爲什麼在這裏呢?這不是顯示錯誤所必需的。 OK,現在我們有一個分配給remQueries的數組{{Maine},「Maryland」,「Massachusetts」}。再次注意領先的空間。

  string[] suggestions = new string[] {"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", 
     "Mississippi", "Missouri", "Montana"}; 

      System.Console.WriteLine("Before Except "); 

      suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); }); 

      var unqiueSugs = from sug in suggestions 
          where !remQueries.Any(q => q.Equals(sug, StringComparison.OrdinalIgnoreCase)) 
          select sug; 

我注意到「unique」在這裏拼寫錯了。

查詢是「看在每一個建議,刪除正好等於任何建議,‘緬因’,」馬里蘭」,或‘馬薩諸塞州’。此外,請注意前導空格。

  if (unqiueSugs != null) 

這是不必要的。查詢對象永遠不會爲空。

  { 
       suggestions = unqiueSugs.ToArray(); 

查詢執行。因爲「緬因」號就行了,它被過濾掉。如果「馬里蘭」號將被過濾掉就行了,但它不是。「馬里蘭」和「馬里蘭州」是不同的字符串。

  } 

      System.Console.WriteLine("\n After Except "); 
      suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); }); 
     } 

所以結果是正確的。我懷疑你的錯誤是你相信「修剪」從字符串中刪除所有空格。它不是。它從字符串的開頭和結尾刪除空格。

你不應該使用Replace來擺脫字符串中的所有空格,因爲當然「紐約」和「羅德島」可能在那裏,你不希望從它們中刪除空格。正確的邏輯是在逗號第一個上進行分割,然後在所有產生的元素上進行修剪。不要先做修剪!

現在,更重要的是,您將學習如何自己完成這種簡單的程序分析,而不是在每次出現問題時都要求互聯網。我建議學習如何使用調試器。逐步通過你的程序仔細並檢查每一步的方式並比較與你認爲正確的狀態應該是什麼。 聽安靜懷疑。你的大腦會告訴你什麼時候看起來不合適,就像一個意想不到的空間。聽取並跟蹤它。調試是一種像其他任何技能一樣的技能;你通過練習來學習它。

+0

+1真棒回答! – sloth 2010-07-16 16:51:07