Определите «правильно».
i18n сортировка полностью зависит от вашего региона.
Итак, Я полностью согласен с PA в том, что это не ошибка: поведение Sort по умолчанию работает так, как задумано. чтобы i18n работал правильно.
Как упоминает Герри, TStringList.Sort использует AnsiCompareStr и >AnsiCompareText (в нескольких строках я объясню, как это делается).
Но: TStringList является гибким, он содержит Sort, CustomSort и CompareStrings, которые являются виртуальными (так что вы можете переопределить их в классе-потомке)
Кроме того, когда вы вызываете CustomSort, вы можете подключить свою собственную функцию Compare.
В конце этого ответа есть функция Сравнить, которая делает то, что вы хотите:
- Деликатный случай
- Без использования какой-либо локали
- Просто сравните порядковый номер символов строк
Пользовательская сортировка определяется следующим образом:
procedure TStringList.CustomSort(Compare: TStringListSortCompare);
begin
if not Sorted and (FCount > 1) then
begin
Changing;
QuickSort(0, FCount - 1, Compare);
Changed;
end;
end;
По умолчанию метод Sort имеет очень простую реализацию, передавая функцию Compare по умолчанию, называемую StringListCompareStrings:
procedure TStringList.Sort;
begin
CustomSort(StringListCompareStrings);
end;
Таким образом, если вы определяете свой собственный метод Compare, совместимый с TStringListSortCompare, вы можете определить свою собственную сортировку.
TStringListSortCompare определяется как глобальная функция, принимающая TStringList и два индекса. ссылаясь на элементы, которые вы хотите сравнить:
type
TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
Вы можете использовать StringListCompareStrings в качестве руководства для реализации собственного:
function StringListCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := List.CompareStrings(List.FList^[Index1].FString,
List.FList^[Index2].FString);
end;
Итак, по умолчанию TStringList.Sort ссылается на TList.CompareStrings:
function TStringList.CompareStrings(const S1, S2: string): Integer;
begin
if CaseSensitive then
Result := AnsiCompareStr(S1, S2)
else
Result := AnsiCompareText(S1, S2);
end;
Которые затем используют базовую функцию Windows API CompareString с языковым стандартом пользователя по умолчанию LOCALE_USER_DEFAULT:
function AnsiCompareStr(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1),
PChar(S2), Length(S2)) - 2;
end;
function AnsiCompareText(const S1, S2: string): Integer;
begin
Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1),
Length(S1), PChar(S2), Length(S2)) - 2;
end;
Наконец, нужная вам функция Сравнить. Опять ограничения:
- Деликатный случай
- Без использования какой-либо локали
- Просто сравните порядковый номер символов строк
Это код:
function StringListCompareStringsByOrdinalCharacterValue(List: TStringList; Index1, Index2: Integer): Integer;
var
First: string;
Second: string;
begin
First := List[Index1];
Second := List[Index2];
if List.CaseSensitive then
Result := CompareStr(First, Second)
else
Result := CompareText(First, Second);
end;
Delphi не закрыта, как раз наоборот: часто это действительно гибкая архитектура.
Часто достаточно немного покопаться, чтобы увидеть, где можно зацепиться за эту гибкость.
--jeroen
person
Community
schedule
01.02.2010
_
передA
, поэтому TStringlist, по крайней мере, соответствует ОС. - person Lieven Keersmaekers   schedule 01.02.2010