Создание кастомного сортера для сортировки числовых данных с плавающей точкой в TListView на Delphi
Введение
При работе с компонентом TListView в Delphi часто возникает необходимость в кастомизации сортировки данных. В частности, это касается числовых данных с плавающей точкой, которые не сортируются корректно с использованием стандартных методов сортировки. В данной статье мы рассмотрим, как создать кастомный сортер для TListView, который будет правильно обрабатывать числовые данные с плавающей точкой.
Проблема с сортировкой чисел с плавающей точкой
Пользователь Brad столкнулся с проблемой, при которой сортировка TListView работала корректно для всех типов данных, за исключением чисел с плавающей точкой. Он попытался создать собственную функцию сортировки cssFloat и соответствующую функцию сравнения CompareFloat, но сортировка все еще не работала должным образом.
Подход к решению
Для решения проблемы Brad использовал функцию проверки валидности числа с плавающей точкой IsValidFloat, которая возвращала статус валидности строки. Если одна из строк не представляла собой валидное число, функция сравнения возвращала 0, что позволяло правильно упорядочить строки, содержащие числа и не числа. В противном случае, если обе строки представляли валидные числа, использовалась функция CompareFloat для сравнения.
function CompareFloat(AStr1, AStr2: string): Integer;
var
nInt1, nInt2: extended;
begin
nInt1:=StrToFloatDef(AStr1, -1);
nInt2:=StrToFloatDef(AStr2, -1);
if nInt1 > nInt2 then Result := 1
else if nInt1 = nInt2 then Result := 0
else Result := -1;
end;
function IsValidFloat(const S: string; var E: extended): Boolean;
begin
Result := TRUE;
try
E := StrToFloat(S);
except
on EConvertError do
begin
E := 0;
Result := FALSE;
end;
end;
end;
procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
var
i1, i2: extended;
LvSortStyle: TLvSortStyle;
begin
case Column.Index of
0: LvSortStyle := cssNumeric;
1: LvSortStyle := function(i2, i1: extended): Integer
begin
Result := ord(IsValidFloat(ListView1.Items[Column.Index].Caption, i1) or IsValidFloat(ListView1.Items[Column.Index].Caption, i2));
if Result <> 0 then
Exit(Result);
Result := CompareFloat(StrClippper(ListView1.Items[Column.Index].Caption, ' ', True), StrToFloatDef('', -1));
var r1, r2: extended;
r1 := IsValidFloat(ListView1.Items[i].Caption, e1);
r2 := IsValidFloat(ListView1.Items[i].Caption, e2);
Result := ord(r1 or r2);
if Result <> 0 then
Result := CompareFloat(e2, e1);
end;
2: LvSortStyle := cssAlphaNum;
else
LvSortStyle := cssNumeric;
end;
ListView1.CustomSort := LvSortStyle;
ListView1.SortType := stBoth;
end;
Альтернативный подход
Также Brad предложил альтернативный вариант функции CompareFloat, использующий функцию StrToFloatDef с обработкой возможных ошибок конвертации. Это позволяет избежать использования try..except, который является более затратной операцией.
function CompareFloat(AStr1, AStr2: string): Integer;
var
nInt1, nInt2: extended;
begin
nInt1 := StrToFloatDef(AStr1, -1);
nInt2 := StrToFloatDef(AStr2, -1);
if nInt1 > nInt2 then
Result := 1
else if nInt1 = nInt2 then
Result := 0
else
Result := -1;
end;
Подтвержденное решение
После нескольких часов поиска решения, Brad понял, что проблема заключалась в том, что функция CompareFloat сравнивала целые числа, а не числа с плавающей точкой. Он использовал функцию IsValidFloat для проверки, является ли значение числом, и только после этого сравнивал их. Также Brad упомянул, что для более эффективной работы можно использовать функцию TryStrToFloat из модуля SysUtils.
Заключение
В данной статье мы рассмотрели, как Brad столкнулся с проблемой сортировки числовых данных с плавающей точкой в TListView на Delphi, и предложили несколько подходов к решению этой проблемы. Важно помнить, что при работе с числами с плавающей точкой следует тщательно обрабатывать возможные ошибки конвертации и использовать специальные функции для корректного сравнения значений.
Создание кастомного сортера для корректной сортировки числовых данных с плавающей точкой в компоненте `TListView` на Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.