#.net #vb.net #sorting #string-comparison
#.net #vb.net #сортировка #сравнение строк
Вопрос:
У меня есть простая процедура для поиска следующего объекта на основе свойства name в неупорядоченной коллекции объектов. Я просматриваю коллекцию и собираю все имена, List(of String)
добавляя любые имена, которые являются >
моим текущим именем, что должно дать список всего, что идет после текущего ключа. Затем я сортирую список, используя .Sort()
метод по умолчанию List(of String)
, и беру первый элемент в списке, который должен быть моим следующим элементом. Я делаю обратное, чтобы найти предыдущий элемент, добавляю все элементы <
с моим текущим именем, сортирую и беру последний элемент в списке.
Однако этот метод пропускает некоторые элементы. Например, у меня есть элементы с именами 1210, 1210-ADA и 1210_ADA_DB. Используя этот метод, получение следующего элемента пропускает средний элемент 1210-ADA и находит 1210_ADA_DB, но поиск предыдущего элемента, похоже, работает.
Если мой процесс верен, мое единственное объяснение заключается в том, что операторы <
and >
сравниваются иначе, чем .Sort()
метод. Это правда? В чем различия?
Код для поиска следующего элемента:
Dim Key As String = Name
Dim NameList As New List(Of String)
For Each obj As T In Collection
Dim ObjKey As String = Obj.Key
If ObjKey > Key Then
NameList.Add(ObjKey)
End If
Next
If NameList.Count = 0 Then Return Nothing
NameList.Sort()
Dim NextKey As String = NameList.First
Комментарии:
1. Вместо того, чтобы описывать свой код, почему бы вам не опубликовать свой код?
Ответ №1:
Я думаю, вы уже нашли, в чем может быть проблема. Но для аннотирования вас укусило некоторое поведение совместимости с VB6. По умолчанию для параметра Compare используется двоичный файл, который использует строку.CompareOrdinal() . Не то, что использует List.Sort(). Опция Сравнить текст использует CultureInfo.CompareInfo.Compare() с CompareOptions.Игнорируйте ширину, CompareOptions.Игнорируйканатип, сравнивай варианты.Параметры игнорирования. Также не то, что использует List.Sort().
Избегайте операторов и используйте String .Вместо этого Compare() .
Ответ №2:
мое единственное объяснение заключается в том, что операторы < и> сравниваются иначе, чем метод .Sort() . Это правда?
Нет. Sort
внутренне использует String.IComparable(Of String).CompareTo
метод, который дает результаты, согласующиеся с <
и >
.
Однако это верно только до тех пор, пока вы не изменили Option Compare
для проекта или текущего файла. Это изменит поведение <
и >
, но не вышеупомянутого метода.
Комментарии:
1. Я не изменил параметры сравнения. В соответствии с настройками моего проекта параметр Compare имеет значение binary, что, я бы предположил, является значением по умолчанию.
2. Вы привели меня к моему ответу, но < и >, по-видимому, все еще отличаются от String . Кроме того, документация для
CompareTo
saysThis method performs a word (case-sensitive and culture-sensitive) comparison using the current culture.
иOption Compart Text
saysbases string comparisons on a case-insensitive, textual sort order determined by your application's locale.
3. @Kratz То, что вы процитировали, имеет значение только для
Option Compare Text
. ПриOption Compare Binary
этом они ведут себя одинаково (с учетом регистра, с учетом культуры).4.
Option Compare Binary bases string comparisons on a sort order derived from the internal binary representations of the characters.
кроме того, теперь, когда я знаю, что мой проект настроенbinary
, поведение моего кода доказывает, что они разные. В моем примере-
сравнение отличалось от_
. Я заменил>
на String . Сравните (чтобы он сравнивался таким же образом), и теперь он работает хорошо.