Delphi TStringList CustomSort по имени

Я пытаюсь отсортировать TStringList в части имени. Для этого я использую метод customSort.

Я покажу вам небольшой пример:

    function CompareString(List : TStringList; Index1, Index2 : integer) : integer;
    begin
        result := AnsiCompareText(List.Names[Index1], List.Names[Index2]);
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        Memo2.Clear;
        Liste.CustomSort(CompareString);     
        Memo2.Lines.Append(Liste.GetText)
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        Liste := TStringList.Create;
        Liste.Append('INFOS_NEGOCE=NUM_CDE');
        Liste.Append('INFOS_NEGOCE=DATE_CDE');
        Liste.Append('INFOS_NEGOCE=NOM_REPERTOIRE_ENT');
        Liste.Append('INFOS_NEGOCE=NOM_CONTACT');     
        Memo1.Lines.Clear;
        Memo1.Lines.Append(Liste.GetText)
    end;

Сортировка дает мне такой результат:

INFOS_NEGOCE=NOM_REPERTOIRE_ENT

INFOS_NEGOCE=NOM_CONTACT

INFOS_NEGOCE=NUM_CDE

INFOS_NEGOCE=DATE_CDE

Я думаю, что сортировка НЕ ​​изменяет порядок строки (имя всегда INFOF_NEGOCE).

2 ответа

function CompareString(List : TStringList; Index1, Index2 : integer) : integer;
begin
  Result := AnsiCompareText(List.Names[Index1], List.Names[Index2]);
  // If you want to sort equal strings then on the Values
  if Result = 0 then Result := AnsiCompareText(List.ValueFromIndex[Index1], List.ValueFromIndex[Index2]);
  // Or if you want to keep the original order
  { if Result = 0 then Result := Index1-Index2; --- qv : this won't work!}
end;

Result будет установлен на 0 по вашему коду, если Names были равны Если они равны, выберите, какие дополнительные критерии вы хотите использовать для сортировки элементов с одинаковыми именами.


Как правильно заметил Уве Раабе, "оригинальный порядок" не сработает.

Но еще не все потеряно. Обычно объект, включенный в список Tstringlist, не используется. Если он доступен, то перед сортировкой попробуйте

for i := 0 to pred(List.Count) do List.Objects[i] := TObject(i);

и сортировка становится

function CompareString(List : TStringList; Index1, Index2 : integer) : integer;
begin
  Result := AnsiCompareText(List.Names[Index1], List.Names[Index2]);
  // If you want to sort equal strings then on the Values
  if Result = 0 then Result := AnsiCompareText(List.ValueFromIndex[Index1], List.ValueFromIndex[Index2]);
  // Or if you want to keep the original order
  if Result = 0 then Result := integer(List.Objects[Index1])-integer(List.Objects[Index2]);
end;

но было бы намного проще, если бы мы раскрыли секрет того, каким должен быть "правильный" порядок.

Сортировка выполняется с помощью QuickSort. Это означает, что порядок идентичных предметов (как видно по сортировке) не определен.

См. Быстрая сортировка - Повторные элементы

Другие вопросы по тегам