Delphi中Stringlist的自定义排序(将函数地址做为参数)

近日,在编制一个程序过程,因为数据量较小,就使用了stringlist来暂存数据。在使用过程中,遇到了一个问题。Stringlist字符串列表的默认排序方法是按ASCII码的方式进行排序,如3,10,9排序时,结果为10,3,9.不符合程序的要求,于是尝试着使用字符串列表的自主义排序方法,这时需要传入一个function类的参数,因为习惯于使用PYTHON语言,所以直接编写民了一个按数值降序排列的排序函数,并将函数名传给了stringlistrr的CustomSort方法,结果提示:Incompatible types: ‘regular procedure and method pointer‘。大致意思是:不匹配的类型:需要一个方法、过程的指针类型。

为了解决这个问题,到网上查找资料,发现这个问题经常会遇到,但是各个解答要不就是看不懂,要不就是运行不成功,经过多次尝试,最终解决了这个问题。

通过分析源代码,结合网上程序,理清了网上的解决思路:1、在type处,定义一个function类型,.如:Tfunc=function(list: TStringList; index1,index2: Integer): Integer;  2、定义一个全局变量:如:myfunc:Tfunc;

3、编写一个自定义的排序程序:如以下程序

function curmsort(list: TStringList; index1,
  index2: Integer): Integer;
var
  value1, value2: Integer;
begin
  value1 := StrToInt(list.Strings[index1]);
  value2 := StrToInt(list.Strings[index2]);
  if value1> value2 then
    Result :=  -1
  else if value1< value2 then
    Result := 1
  else
    Result := 0;
end;

4、在排序时,首先执行myfunc:=curmsort;(将自定义的函数名赋值给myfunc变量。)list.sorted:=False;,关闭排序,然后执行list.CustomSort(myfunc);

按照这个思路,最终也完成了自定义排序(将函数地址传参)的功能。

完成后,回顾整个程序,通过对比、思考、实验,发现第一、二步和最后一步的将函数名赋值给函数类型的变量都是可以省略的,关键的是自己定义的排序函数curmsort不能进行声明,只要声明了就不好使,个人感觉应该是因为在不声明的情况下,函数名仅代表的是函数的内存地址,而不是执行函数的返回值。前边的失败是因为将函数进行了声明,这时函数名代表了函数执行后的返回值,所以才导致类型不匹配。

例程如下:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  TForm1 = class(TForm)
    lst1: TListBox;
    lst2: TListBox;
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
//注意,自定义的函数curmsort不能进行声明。
    { Private declarations }
  public
    { Public declarations }
  end;

var

  Form1: TForm1;

implementation

{$R *.dfm}
function curmsort(list: TStringList; index1,
  index2: Integer): Integer;   //写函数时,函数名前不能加Tform1等限制。
var
  value1, value2: Integer;
begin
  value1 := StrToInt(list.Strings[index1]);
  value2 := StrToInt(list.Strings[index2]);
  if value1> value2 then
    Result :=  -1
  else if value1< value2 then
    Result := 1
  else
    Result := 0;
end;

procedure TForm1.btn1Click(Sender: TObject);
var list:TStringList;i:Integer;
begin
  list:=TStringList.Create;
  for i:=0 to 30 do
    begin
      list.Add(IntToStr(Random(3000)));
    end;
  lst1.Items.Assign(list);

  list.Sorted:=False;
  list.CustomSort(curmsort);
  lst2.Items.Assign(list);
end;

end.

原文地址:https://www.cnblogs.com/lzszs/p/10716714.html

时间: 2024-10-06 23:26:40

Delphi中Stringlist的自定义排序(将函数地址做为参数)的相关文章

Delphi中stringlist分割字符串的用法

Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaText 2.Delimiter &DelimitedText 3.Names &Values &ValueFromIndex 先看第一个:CommaText.怎么用呢? const constr :String = 'aaa,bbb,ccc,ddd'; var strs :TStrin

NGUI中的Table自定义排序

写一个类,重写Sort方法,用自定义的比较器来  自定义 排序规则(例如:武将的排序,可以按国家.星级.等级排序) UITable 第123行 /// <summary> /// Want your own custom sorting logic? Override this function. /// </summary> protected virtual void Sort (List<Transform> list) { list.Sort(UIGrid.So

Java中Collections类的排序sort函数两种用法 (转http://viver120.blog.163.com/blog/static/60072482013010111228695/)

java中的Colletions类主要实现列表List的排序功能.根据函数参数的传递,具体的排序可以分为 : 1.  自然排序(natural ordering). 函数原型:sort(List<T> list)说明:参数是要参与排序列表的List对象                                                               实例说明:参与排序的列表的元素Student必须实现Comparable接口的public int compareTo(

Delphi中返回类型为string的函数的一个陷阱(不是很懂)

如果类的一个成员函数的返回值是string类型,需要注意一个问题 其返回值可能是错误的 例如函数的实现如下 function GetString( s: string ): string;begin  Result := Result + s;end; 调用方式如下: procedure test();var  i: Integer;  s: string;begin    s := '';    s := GetString( IntToStr( 1 ) );    s := GetStrin

C++中sort排序之自定义排序cmp(入门)

咳咳,第一次写这种博客,介绍一下sort的自定义排序cmp函数: sort和cmp的实现需要的头文件有: #include<algorithm> using namespace std; sor()是C++标准库中的排序函数,使用很方便,传进去数组的起始和结束地址就行,注意是左闭右开,默认的排序是<,从小到大,不过可以自己写一个cmpare()来自定义,下面缩写cmp()函数.cmp()函数的返回值要是bool,核心之处也是比较,因为sort默认是从小到大,所以在cmp如果还是要从小到大

Lucene 中自定义排序的实现

使用Lucene来搜索内容,搜索结果的显示顺序当然是比较重要的.Lucene中Build-in的几个排序定义在大多数情况下是不适合我们使用的.要适合自己的应用程序的场景,就只能自定义排序功能,本节我们就来看看在Lucene中如何实现自定义排序功能. Lucene中的自定义排序功能和Java集合中的自定义排序的实现方法差不多,都要实现一下比较接口. 在Java中只要实现Comparable接口就可以了.但是在Lucene中要实现SortComparatorSource接口和 ScoreDocCom

Delphi中的Free和Nil和freeandnil函数

Delphi中的Free和Nil 在Delphi中释放对象资源时一般用Obj.Free(Obj为一个实例名),不过程Delphi中还有一个FreeAndNil(对象名)函数,那么用哪个好呢?Free和Nil的本质又都是什么呢? 在Delphi中一个对象名只是一个指向该对象的指针,可以有多个指针指向同一个对象地址.Nil是将指针置空,而Free则将指针指向的对象销毁掉.如下所示: Obj.Free; //将Obj所指向的对象销毁. Obj:= nil; //将Obj指针置空.如果将上面的一句放在后

Delphi中SendMessage使用说明 good

Delphi中SendMessage使用说明 SendMessage基础知识 函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回. 函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam): 参数: hWnd:其窗口程序将接收消息的窗口的句柄.如果此参数为HWND_BRO

一步一步跟我学习lucene(13)---lucene搜索之自定义排序的实现原理和编写自己的自定义排序工具

自定义排序说明 我们在做lucene搜索的时候,可能会需要排序功能,虽然lucene内置了多种类型的排序,但是如果在需要先进行某些值的运算然后在排序的时候就有点显得无能为力了: 要做自定义查询,我们就要研究lucene已经实现的排序功能,lucene的所有排序都是要继承FieldComparator,然后重写内部实现,这里以IntComparator为例子来查看其实现: IntComparator相关实现 其类的声明为 public static class IntComparator exte