2012-11-16 23 views
7

我正在嘗試使用對象名稱屬性對對象的泛型列表進行排序。我使用LINQ和下面的表達式完全不是那麼回事:Linq OrderBy在泛型列表上返回不完全按字母順序排列的列表

var query = possibleWords.OrderBy(x => x.Name.ToLower()).ToList(); 
foreach (Word word in query) //possibleWords.OrderBy(word => word.Name)) 
    { 
      listWords.Items.Add(word.Name); 
    } 

「查詢」現在應該包含訂購的商品清單,如果我理解正確和項目應該被添加到列表框中命名listWords。

但是輸出是這樣的:

http://screencast.com/t/s1CkkWfXD4(遺憾的URL鏈接,但這麼莫名其妙地把我鎖我的賬戶,我顯然不能用這個新發布的圖像)。

列表框幾乎按字母順序排列,但不完全。出於某種原因,「aa」和「aaaa」是最後一個。可能是什麼原因,以及如何解決它?

在此先感謝。

闡述的要求

此代碼,在Visual Studio中輸入並執行時:

 List<Word> words = new List<Word>(); 

     words.Add(new Word("a")); 
     words.Add(new Word("Calculator")); 
     words.Add(new Word("aaa")); 
     words.Add(new Word("Projects")); 
     words.Add(new Word("aa")); 
     words.Add(new Word("bb")); 
     words.Add(new Word("c")); 

     IEnumerable<Word> query = words.OrderBy(x => x.Name.ToLower()).ToList(); 

     foreach (Word word in query) 
     { 
      Console.WriteLine(word.Name); 
     } 

給我下面的輸出:

a 
bb 
c 
Calculator 
ccc 
Projects 
aa 
aaa 

這是不正確排序:第一個「a」是正確的,但隨後的「aa」和「aaa」條目被髮送到列表的底部。

我不太瞭解字符集和編碼,所以我可能在這裏犯了一個菜鳥錯誤。但是在這種情況下,我不認識到可能是什麼,對於爲什麼第一個「a」正確排序,我會有點困惑,但第二個和第三個「aa」和「aaa」不是!

進一步闡述 - 字類

[Serializable()] 
public class Word 
{ 
    [System.Xml.Serialization.XmlAttribute("Name")] 
    public string Name { get; set; } 

    public Word(string name) 
    { 
     Name = name; 
    } 

    public Word() { } //Parameter less constructor neccessary for serialization 

} 

原因和解決

像@Douglas建議,這個問題是通過提供StringComparer.InvariantCultureIgnoreCase比較器的排序依據的方法解決。

在進一步的研究,似乎都在的FindAll和排序依據的方法(可能還有其他人)使用丹麥文化(DA-DK)時遇到問題。可能有其他方法或文化失敗,但da-DK文化和FindAll + OrderBy方法肯定無法按預期工作。

OrderBy方法存在此線程中描述的問題(錯誤排序)。 FindAll方法有一個類似的非常奇怪的問題:假設我們有一個條目列表:a,aa,aaa和aaaa。當使用FindAll(x => x.StartsWith(「a」))時,它只會返回「a」NOT aa,aaa和aaaa。如果使用StartsWith(「aa」),它將正確地找到aa以及aaa和aaaa。當使用StartWith(「aaa」)時,它將再次找不到aaaa,只有aaa!這似乎是該框架中的一個錯誤。

+0

請確保您稍後不要添加一些項目。即驗證'query.Count()'等於列表中的字數。另外請確保您只使用英文字符。 –

+0

如果你使用winforms,你可以嘗試使用: listBox1.Sorted = true;而不是linq orderby,看看它是否可以解決問題 – RAS

+1

而不是張貼圖片鏈接,你可以發佈一個簡單的例子顯示你的情況? –

回答

6

你能不能嘗試更換:

IEnumerable<Word> query = words.OrderBy(x => x.Name.ToLower()).ToList(); 

...有:

IEnumerable<Word> query = words.OrderBy(x => x.Name, 
    StringComparer.InvariantCultureIgnoreCase); 

有一個很小的機會,這是一個奇怪的文化問題。

+1

+1。我認爲這是在這一點上唯一合理的解釋 - OP的文化比較遠沒有...... –

+0

這實際上是做了詭計。我不明白爲什麼,除非你說道格拉斯,一些奇怪的文化問題。我沒有使用任何特別的時髦文化,所以很奇怪。但它運作良好,所以我想我現在可以去睡覺了,並且試着重新回到妻子的美好生活中。非常感謝! –

+0

嘗試檢查'CultureInfo.CurrentCulture'和'CultureInfo.CurrentUICulture'的值。但是,先來一個美好的夜晚吧:-) – Douglas

2

最有可能你最後一個「a」是一些不同的(非ASCII)字符。檢查字符代碼(int)("a"[0])以查看它是否與英語「a」相同。

如果是這樣的話,排序並不存在問題 - 沒有什麼可以解決的(除非更好地理解你的數據)。

+0

所有條目都通過代碼添加到文本中,如:ListObj.Add(「a」),ListObj.Add(「aaaa」),ListObj.Add(「Calculator」),ListObj.Add(「bbb」)等。 –

+1

@ user1830478,我不確定你想說什麼與您的評論。你是否暗示C#源代碼只能包含ASCII字符(顯然是false)? –

+0

嘗試打印到控制檯或通過messagebox,'MessageBox.Show(string.Format(「{0}」,(int)'a'));'&看看它的** 97 **,複製和粘貼 – S3ddi9

5

下面的代碼輸出預期的結果:

class Word 
{ 
    public Word(string str) 
    { 
     Name = str; 
    } 

    public string Name { get; private set; } 
} 

public static void Main(string[] args) 
{ 
    List<Word> words = new List<Word>(); 

    words.Add(new Word("a")); 
    words.Add(new Word("Calculator")); 
    words.Add(new Word("aaa")); 
    words.Add(new Word("Projects")); 
    words.Add(new Word("aa")); 
    words.Add(new Word("bb")); 
    words.Add(new Word("c")); 

    IEnumerable<Word> query = words.OrderBy(x => x.Name.ToLower()).ToList(); 

    foreach (Word word in query) 
    { 
     Console.WriteLine(word.Name); 
    } 
} 

輸出:

a 
aa 
aaa 
bb 
c 
Calculator 
Projects 

更新: 好的,神祕解決(種)。 如果你執行你的代碼之前執行以下操作:

var cultureInfo = new CultureInfo("da-DK"); 
Thread.CurrentThread.CurrentCulture = cultureInfo; 
Thread.CurrentThread.CurrentUICulture = cultureInfo; 

你得到「不正確」輸出:

a 
bb 
c 
Calculator 
Projects 
aa 
aaa 

丹麥辭書比較顯然,規則是不同的。 下面是我在網上(http://stackoverflow.com/questions/4064633/string-comparison-in-java)發現了一個解釋:

注意,這是非常依賴於積極的語言環境。例如,在丹麥,我們有一個字符「å」,過去這個字符拼寫爲「aa」,與兩個單詞a非常不同。因此,丹麥的排序規則將兩個連續的a與「å」等同起來,這意味着它遵循z。這也意味着丹麥語詞典的排序與英語或瑞典語不同。

+0

這很奇怪。我研究過類定義,除了將字符串參數傳遞給單詞類中的公共字段之外,我不在構造函數中進行任何操作。 –

+0

我剛剛嘗試使用純字符串而不是Word對象 - 仍然是相同的輸出。但似乎有幾個人試過相同的代碼,結果正確,所以我很難過! –

+0

我也嘗試複製你的例子逐字,沒有給出正確的排序順序。很奇怪。 –