2012-02-20 1 views
13

У меня есть список, как этотСтрока сортировки проблема в C#

List<string> items = new List<string>(); 
    items.Add("-"); 
    items.Add("."); 
    items.Add("a-"); 
    items.Add("a."); 
    items.Add("a-a"); 
    items.Add("a.a"); 

    items.Sort(); 

    string output = string.Empty; 
    foreach (string s in items) 
    { 
     output += s + Environment.NewLine; 
    } 

MessageBox.Show(output); 

Выход возвращается в

- 
. 
a- 
a. 
a.a 
a-a 

, где, как я ожидал результатов, как

- 
. 
a- 
a. 
a-a 
a.a 

Любая идея почему «аа» не приходит раньше «аа», где «а-» предшествует «а».

ответ

4

Если вы хотите, чтобы ваша строку сортировать по основываться на фактическом значении байт в отличие от правил, определяемых текущей культурой, которую вы можете сортировать по Ординалу:

items.Sort(StringComparer.Ordinal);

Это позволит сделать результаты согласованными во всех культурах (но это приведет к неинтуитивным сортировкам «14», предшествующим «9», что может быть или не быть тем, что вы ищете).

+0

Спасибо Jared, Не могли бы вы рассказать мне, как я могу сортировать, если данные находятся в столбце DataTable 'DataTable dataTable = new DataTable(); dataTable.Columns.Add ("Item", typeof (string)); dataRow = dataTable.NewRow(); dataRow ["Item"] = "a-a"; dataTable.Rows.Add (dataRow); dataRow = dataTable.NewRow(); dataRow ["Item"] = "a.a"; dataTable.Rows.Add (dataRow); DataRow [] rows = dataTable.Select ("", "Item ASC"); ' – Satya

4

Sort метод List<> класса зависит от умолчанию string компаратора в .NET Framework, которая на самом деле является экземпляр текущего CultureInfo в Thread в.

CultureInfo указывает алфавитный порядок символов, и кажется, что по умолчанию используется порядок, отличный от того, что вы ожидаете.

При сортировке можно указать конкретный CultureInfo, тот, который вы знаете, будет соответствовать вашим требованиям сортировки, выборки (немецкая культура):

var sortCulture = new CultureInfo("de-DE"); 
items.Sort(sortCulture); 

Более подробную информацию можно найти здесь:
http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx
http://msdn.microsoft.com/de-de/library/system.stringcomparer.aspx

+0

Непонятно, что «-» (дефис) предшествует «.» (Точка) и «а-» перед «а»; почему бы не «aa» до «aa»? – Satya

+0

Теоретически, текущая культура могла бы считать '.' и' -' одинаковым порядком. Метод '.Sort' является« неустойчивым », что означает, что порядок равных элементов –

+1

Я тестировал на английском языке и получил те же результаты, что и OP. Даже при тестировании с использованием String.Compare у меня никогда не было 0 (равно). Я либо получил -1, либо 1, в зависимости от того, что было первым. это, вероятно, не проблема с методом .Sort. –

15

Я подозреваю, что в последнем случае «-» обрабатывается по-другому из-за специфических для культуры настроек (возможно, как «тире», а не «минус» в первых строках). MSDN warns об этом:

Сравнения использует текущую культуру для получения культуры конкретной информации, таких как правила обсадных и алфавитный порядок отдельных символов. Например, культура может указывать, что определенные комбинации символов обрабатываются как один символ, или символы верхнего и нижнего регистра сравниваются определенным образом, или что порядок сортировки символа зависит от символов , которые предшествуют или следуйте за ним.

см Также в this MSDN page:

В .NET Framework использует три различных способа сортировки: слово сортировки, строка сортировки и порядкового сортировки. Сортировка Word выполняет сопоставимое с культурой сравнение строк. У некоторых неалфариновых символов могут быть назначены специальные весовые коэффициенты ; например, дефис («-») может иметь очень небольшой вес, назначенный ему, чтобы «курятник» и «кооператив» отображались рядом друг с другом в отсортированном списке. Строковая сортировка аналогична сортировке слов , за исключением того, что особых случаев нет; поэтому все знаки несимметричного символа присутствуют перед всеми буквенно-цифровыми символами. Обычная сортировка сравнивает строки на основе значений Unicode каждого элемента строки.

Таким образом, дефис получает специальную обработку в режиме сортировки по умолчанию, чтобы сделать слово более «естественным».

Вы можете получить «нормальный» порядковый вид, если вы специально включите его:

 Console.WriteLine(string.Compare("a.", "a-"));     //1 
    Console.WriteLine(string.Compare("a.a", "a-a"));    //-1 

    Console.WriteLine(string.Compare("a.", "a-", StringComparison.Ordinal)); //1 
    Console.WriteLine(string.Compare("a.a", "a-a", StringComparison.Ordinal)); //1 

Чтобы отсортировать оригинальную коллекцию с помощью порядкового использования сравнения:

 items.Sort(StringComparer.Ordinal); 
+0

Я думаю, что вы ее взломали, похоже, проблема в этом вопросе. – ntziolis

+0

@ntziolis: Похоже, это c Действительно. –

+0

Как указать этот исходный сравнитель, если данные находятся в DataColumn DataTable – Satya