Delphi 排序对象列表<;T>;同一比较值集群内的问题
我想使用自己的比较器函数对Delphi 排序对象列表<;T>;同一比较值集群内的问题,delphi,generics,sorting,tobjectlist,Delphi,Generics,Sorting,Tobjectlist,我想使用自己的比较器函数对TObjectList进行排序比较器函数代码如下所示 我希望我的ObjectList能够按照两个方向进行升序和降序排序,为了实现这一点,我使用SysUtil.CompareText,它有两个参数S1和S2,并且按照降序排序,我正好与CompareText结果的符号相反。我不知道是否存在另一种解决方案,如果s1大于S2,则一切正常,反之亦然。但是,如果s1=S2,在正常情况下,列表中没有重新索引,因为列中的所有元素都相同,但相反 Occessed TObjectList按
TObjectList
进行排序比较器函数代码如下所示
我希望我的ObjectList能够按照两个方向进行升序和降序排序,为了实现这一点,我使用SysUtil.CompareText,它有两个参数S1和S2,并且按照降序排序,我正好与CompareText结果的符号相反。我不知道是否存在另一种解决方案,如果s1大于S2,则一切正常,反之亦然。但是,如果s1=S2,在正常情况下,列表中没有重新索引,因为列中的所有元素都相同,但相反
Occessed TObjectList按s1>s2或s1TPerson = class
private
FName: string;
FId: string;
public
property Name: string read FName write FName;
property ID: string read FID write FID;
end;
TPersons = class(TObjectList<TPerson>)
public
constructor Create();
procedure Sort(Direction: string); reintroduce;
end;
procedure TForm4.Button1Click(Sender: TObject);
var
PersonsList: TPersons;
I: Integer;
begin
PersonsList := TPersons.Create;
PersonsList.Sort('Ascending');
for I := 0 to PersonsList.Count - 1 do
ShowMessage(PersonsList[i].Name);
end;
{ TPersons }
constructor TPersons.Create;
var
Person: TPerson;
begin
Person := TPerson.Create;
Person.Name := 'fateh';
Person.ID := '1';
Self.Add(Person);
Person := TPerson.Create;
Person.Name := 'mohamed';
Person.ID := '1';
Self.Add(Person);
Person := TPerson.Create;
Person.Name := 'oussama';
Person.ID := '1';
Self.Add(Person);
// all ids are identical
end;
procedure TPersons.Sort(Direction: string);
var
Comparer : IComparer<TPerson>;
Comparison : TComparison<TPerson>;
begin
if Direction = 'Ascending' then
Comparison := function(const Person1, Person2 : TPerson): Integer
begin
result := CompareText(Person1.ID, Person2.ID);
end;
if Direction = 'Descending' then
Comparison := function(const Person1, Person2 : TPerson): Integer
begin
result := - CompareText(Person1.ID, Person2.ID);
end;
Comparer := TComparer<TPerson>.Construct(Comparison);
inherited Sort(Comparer);
end;
TPerson=class
私有的
FName:字符串;
FId:字符串;
公众的
属性名称:字符串读取FName写入FName;
属性ID:字符串读取FID写入FID;
结束;
TPersons=类(TObjectList)
公众的
构造函数Create();
程序排序(方向:字符串);重新引入;
结束;
程序TForm4.按钮1单击(发件人:ToObject);
变量
人员名单:TPersons;
I:整数;
开始
PersonList:=TPersons.Create;
PersonsList.Sort('升序');
对于I:=0到PersonList。计数-1 do
ShowMessage(PersonsList[i].Name);
结束;
{TPersons}
构造函数TPersons.Create;
变量
个人:TPerson,;
开始
Person:=TPerson.Create;
人名:=‘法蒂赫’;
Person.ID:=“1”;
自我添加(人);
Person:=TPerson.Create;
姓名:=“穆罕默德”;
Person.ID:=“1”;
自我添加(人);
Person:=TPerson.Create;
姓名:=“oussama”;
Person.ID:=“1”;
自我添加(人);
//所有ID都是相同的
结束;
过程TPersons.Sort(方向:字符串);
变量
比较器:IComparer;
比较:t比较;
开始
如果方向=‘上升’,则
比较:=函数(const Person1,Person2:TPerson):整数
开始
结果:=比较文本(Person1.ID,Person2.ID);
结束;
如果方向=‘下降’,则
比较:=函数(const Person1,Person2:TPerson):整数
开始
结果:=-CompareText(Person1.ID,Person2.ID);
结束;
比较器:=TComparer.Construct(比较);
继承排序(比较器);
结束;
如果在正常情况下s1=s2,则列表中没有重新索引,因为列中的所有元素都相同
这是错误的想法。计算机应该按你说的去做,但仅此而已。
如果您告诉计算机这些对象是相等的(换句话说,比较器函数返回零),那么计算机有权将它们按适合其内部排序实现的任何顺序排列
如果您确实希望具有相同ID的对象集群之间有某种特定的顺序,那么这只意味着具有相同ID的对象实际上并不相等,至少不是所有这些对象
当然,如果ID不同,那么对象也会不同。但是,即使这些ID是相同的——只要您关心排序,这就证明了这些对象对您来说仍然不同,并且ID相等不足以指定完全相等的对象。这意味着您应该使用嵌套、级联比较器,使用越来越多的细粒度测试,直到发现差异
Comparison := function(const Person1, Person2 : TPerson): Integer
begin
Result := CompareText(Person1.ID, Person2.ID);
if Result <> 0 then exit;
Result := CompareText(Person1.Name, Person2.Name);
if Result <> 0 then exit;
Result := Person1.Age - Person2.Age;
if Result <> 0 then exit;
Result := GenderCompare(Person1.Sex, Person2.Sex);
if Result <> 0 then exit;
Result := Person1.Salary - Person2.Salary;
if Result <> 0 then exit;
...et cetera
end;
比较:=函数(const Person1,Person2:TPerson):整数
开始
结果:=比较文本(Person1.ID,Person2.ID);
如果结果为0,则退出;
结果:=CompareText(Person1.Name,Person2.Name);
如果结果为0,则退出;
结果:=人1.年龄-人2.年龄;
如果结果为0,则退出;
结果:=性别比较(Person1.Sex,Person2.Sex);
如果结果为0,则退出;
结果:=人员1.工资-人员2.工资;
如果结果为0,则退出;
…等等
结束;
比较是一种数学,一种代数。你证明了一些公理,然后一些理论开始起作用。但只有在公理证明之后,才不超过实际的定理项
您关心具有相同ID的对象的顺序这一事实表明该公理是错误的。比较过程比ID本身更复杂。
您必须制作一个比较器,该比较器只会在真正相等的对象上返回零,换句话说,您不完全关心对象的顺序
试着阅读
如果在正常情况下s1=s2,则列表中没有重新索引,因为列中的所有元素都相同
这是错误的想法。计算机应该按你说的去做,但仅此而已。
如果您告诉计算机这些对象是相等的(换句话说,比较器函数返回零),那么计算机有权将它们按适合其内部排序实现的任何顺序排列
如果您确实希望具有相同ID的对象集群之间有某种特定的顺序,那么这只意味着具有相同ID的对象实际上并不相等,至少不是所有这些对象
当然,如果ID不同,那么对象也会不同。但是,即使这些ID是相同的——只要您关心排序,这就证明了这些对象对您来说仍然不同,并且ID相等不足以指定完全相等的对象。这意味着您应该使用嵌套、级联比较器,使用越来越多的细粒度测试,直到发现差异
Comparison := function(const Person1, Person2 : TPerson): Integer
begin
Result := CompareText(Person1.ID, Person2.ID);
if Result <> 0 then exit;
Result := CompareText(Person1.Name, Person2.Name);
if Result <> 0 then exit;
Result := Person1.Age - Person2.Age;
if Result <> 0 then exit;
Result := GenderCompare(Person1.Sex, Person2.Sex);
if Result <> 0 then exit;
Result := Person1.Salary - Person2.Salary;
if Result <> 0 then exit;
...et cetera
end;
比较:=函数(const Person1,Person2:TPerson):整数
开始
结果:=比较文本(Person1.ID,Person2.ID);
如果结果为0,则退出;
结果:=CompareText(Person1.Name,Person2.Name);
如果结果为0,则退出;
结果:=人1.年龄-人2.年龄;
如果结果为0,则退出;
结果:=性别比较(Person1.Sex,Person2.Sex);
如果结果为0,则退出;
结果:=人员1.工资-人员2.工资;
如果结果为0,则退出;
…等等
结束;
比较是一种数学,一种代数。你证明了一些公理,然后证明了一些理论