Definir " correctamente".
i18n clasificación depende totalmente de su configuración regional.
Por lo tanto, estoy totalmente de acuerdo con PA que esto no es un error: el comportamiento predeterminado Sort funciona como está diseñado para permitir que i18n funcione correctamente.
Como Gerry menciona, TStringList.Sort utiliza AnsiCompareStr y AnsiCompareText (Voy a explicar en pocas líneas cómo se hace eso).
Pero: TStringList es flexible, contiene Ordenar, CustomSort y CompareStrings, todos los cuales son virtuales (por lo que se los puede sustituir en una clase descendiente)
Por otra parte, cuando se llama CustomSort, puede conectar su propia función Comparar.
en el de esta respuesta es un Compare función que hace lo que quiere:
- mayúsculas y minúsculas
- No utilizar cualquier localidad
- Basta con comparar el valor ordinal de los caracteres de las cadenas
CustomSort se define como este:
procedure TStringList.CustomSort(Compare: TStringListSortCompare);
begin
if not Sorted and (FCount > 1) then
begin
Changing;
QuickSort(0, FCount - 1, Compare);
Changed;
end;
end;
Por defecto, el Ordenar método tiene una aplicación muy simple, pasando un defecto Compare función llamada StringListCompareStrings:
procedure TStringList.Sort;
begin
CustomSort(StringListCompareStrings);
end;
Por lo tanto, si define su propio TStringListSortCompare compatible Comparar el método, luego puede definir su propia clasificación.
TStringListSortCompare se define como una función global que toma el TStringList y dos índices de referencia los elementos que desee comparar:
type
TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
Puede utilizar los StringListCompareStrings como una guía para la implementación de su propia:
function StringListCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := List.CompareStrings(List.FList^[Index1].FString,
List.FList^[Index2].FString);
end;
Así, por defecto TStringList.Sort remite a TList.CompareStrings:
function TStringList.CompareStrings(const S1, S2: string): Integer;
begin
if CaseSensitive then
Result := AnsiCompareStr(S1, S2)
else
Result := AnsiCompareText(S1, S2);
end;
Qué a continuación, utilizar la mentira bajo función de la API de Windows con el usuario CompareString regional predeterminada 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;
Finalmente el Compare función que necesita. De nuevo las limitaciones:
- mayúsculas y minúsculas
- No utilizar cualquier localidad
- Basta con comparar el valor ordinal de los caracteres de las cadenas
Este es el código:
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 no está cerrado, todo lo contrario: a menudo es una arquitectura realmente flexible.
A menudo es solo un poco de excavación para ver dónde puede enganchar esa flexibilidad.
--jeroen
Windows también ordena ''' antes de' A', por lo que TStringlist es al menos consistente con el sistema operativo. –
obteniendo resultados que no esperas, no significa que sea un error. No es un error, está diseñado de esta manera para respaldar correctamente la elección del orden de clasificación del usuario (u OS en nombre del usuario). –
Está escribiendo esta pregunta con la presunción de que * es * una forma correcta de ordenar caracteres no alfabéticos. ¿Dónde aparecen las palabras de subrayado en tu diccionario? –