我刚刚开始使用泛型,我目前在多个字段上进行排序时遇到问题.
案例:
我有一个PeopleList作为a TObjectList<TPerson>,我希望能够通过一次选择一个排序字段来制作类似Excel的排序功能,但尽可能保持先前的排序.
编辑:必须可以在运行时更改字段排序顺序.(即,在一种情况下,用户想要排序顺序A,B,C - 在另一种情况下,他想要B,A,C - 在另一个A,C,D中)
让我们说我们有一个未分类的人员列表:
Lastname Age
---------------------
Smith 26
Jones 26
Jones 24
Lincoln 34
Run Code Online (Sandbox Code Playgroud)
现在,如果我按LastName排序:
Lastname ? Age
---------------------
Jones 26
Jones 24
Lincoln 34
Smith 26
Run Code Online (Sandbox Code Playgroud)
然后如果我按年龄排序,我想要这个:
Lastname ? Age ?
---------------------
Jones 24
Jones 26
Smith 26
Lincoln 34
Run Code Online (Sandbox Code Playgroud)
为了做到这一点,我制作了两个比较器 - 一个TLastNameComparer和一个TAgeComparer.
我现在打电话
PeopleList.Sort(LastNameComparer)
PeopleList.Sort(AgeComparer)
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,这不会产生我想要的输出,但是
Lastname ? Age ?
---------------------
Jones 24
Smith 26
Jones 26
Lincoln 34
Run Code Online (Sandbox Code Playgroud)
史密斯,26岁出现在琼斯之前,26岁.所以看起来它没有保留以前的排序.
我知道我只能制作一个比较LastName和Age的比较器 - 但问题是,我必须为TPerson中存在的每个字段组合制作比较器.
是否可以使用多个TComparers做我想做的事情,或者我如何实现我想要的?
仅供参考未来的访问者,这(几乎)是我现在使用的代码.
首先,我创建了一个基类TSortCriterion<T>,TSortCriteriaComparer<T> …
我想使用内置的排序方法对我的通用tobjectlist进行排序.
这是我做的:
//create the list object
myList := TObjectList<MyType>.Create(false);
[...] //populate the list with unsorted entries
//sort the list
myList.sort(@Comparer);
[...]//store sorted results back to array
myList.Destroy;
Run Code Online (Sandbox Code Playgroud)
我的Comparer函数如下所示:
function Comparer(Item1, Item2 : pointer):integer;
begin
result := myCompare(item1, item2);
end;
Run Code Online (Sandbox Code Playgroud)
根据规格,它应该像这样工作.
我得到一个编译器错误E2250 没有这些参数存在'Sort'的重载版本(确切的措辞不同,我使用非英文版的RAD Studio)
我不知道为什么这不应该是有效的Pascal - 你们中的任何人都有洞察力分享这个吗?
*摘要:
请查看德尔福专家的知识渊博的评论.特别是对我来说,我会尝试使用旧的TList/TObjectList作为David建议,并使用hard-cast和TObjectList.List属性作为A.Bouchez建议.我将在未来重构时尝试使用TDynArray.
================================================== ===================
假设我有一个TAtom如下面代码中定义的类.目前,在运行时hundreds最多thousands有TAtom实例stored in a dynamic array.在运行时,我需要对TAtom.X/Y/Z所有现有的TAtom实例进行简单的浮点运算,30每秒多次.
现在,我需要补充的能力adding,inserting,deletingTAtom的实例在运行时.似乎我的选择是(1)请求一个大阵列; (2)坚持动态数组并手动设置SetLength; (3)切换到常规TList; (4)切换到常规TObjectList.
我想避免(1)除非有必要,因为我必须改变很多功能签名.(2)看起来也不好,因为TList/TObjectList似乎为这项任务而生.但是,因为需要使用常规TList/TObjectList进行类型转换,是否可以对可能的性能命中进行一些评论?我的意思是,如果在重写代码之前可以估算性能负担,那将是最好的.如果性能会明显下降,我还可以使用其他技术吗?
此外,我想知道使用TList和TObjectList之间是否存在性能差异?
TAtom = class
public
ElementZ: Integer;
X, Y, Z: Extended;
other variables: other types;
end;
TAAtom = array of TAtom;
Run Code Online (Sandbox Code Playgroud) 我有一个FileEventObjects := TObjectList.Create(True);包含一个或多个对象的TObject列表().对象需要保留在列表中,直到它们被处理.(对象列表在应用程序的持续时间内存在.)
我不完全确定如何从列表中删除已处理的对象.
如果我这样做,对象是否会被"释放" FileEventObjects.Delete(i)
是否有任何有用的TObjectLists实例的链接?
问候,彼得.
我的代码有问题,它使用泛型类型.为什么编译器不知道传递的list(Result)是一个TObjectList<TItem>(TItem是Tin的类型TItems)?
接口:
type
TItem = class
end;
type
IItemsLoader = interface
procedure LoadAll(AList : TObjectList<TItem>);
end;
type
TItemsLoader = class(TInterfacedObject, IItemsLoader)
public
procedure LoadAll(AList : TObjectList<TItem>);
end;
type
IItems<T : TItem> = interface
function LoadAll : TObjectList<T>;
end;
type
TItems<T : TItem> = class(TInterfacedObject, IItems<T>)
private
FItemsLoader : TItemsLoader;
public
constructor Create;
destructor Destroy; override;
function LoadAll : TObjectList<T>;
end;
Run Code Online (Sandbox Code Playgroud)
执行:
procedure TItemsLoader.LoadAll(AList: TObjectList<TItem>);
begin
/// some stuff with AList …Run Code Online (Sandbox Code Playgroud) 我使用TObjectList(Delphi 2007)存储大量数据 - 我希望有大约30万个元素甚至更多.但是,当创建列表时,它的默认大小设置为仅存储四个元素,如果一个尝试添加第五个元素则为8,如果一个尝试添加第九个元素则为16,依此类推.数字可能已关闭,但我认为工作正确.这样做的问题是必须将所有元素从内存的释放部分复制到新扩展列表迁移的新内存块.我想设置一个特定的初始大小并释放(或撤消内存的保留,因为保留和分配不是相同的事情)列表已分配/保留的任何未使用的空间.这可能不是很多代码,但我认为应该以问答形式对这个问题进行永久,可靠的引用.
我正在尝试在Delphi XE8中创建TObjectList类,但是当我尝试获取值时,我会收到错误.
编译器错误消息:"[dcc32错误]:无法访问私有符号{System.Generics.Collections} TList.GetItem"
这是我的代码:
unit Unit2;
interface
uses
Classes, System.SysUtils, System.Types, REST.Types, System.JSON, Data.Bind.Components,
System.RegularExpressions, System.Variants,
Generics.Collections;
type
TTruc = class
public
libelle : string;
constructor Create(pLibelle : string);
end;
TListeDeTrucs = class(TObjectList<TTruc>)
private
function GetItem(Index: Integer): TTruc;
procedure SetItem(Index: Integer; const Value: TTruc);
public
function Add(AObject: TTruc): Integer;
procedure Insert(Index: Integer; AObject: TTruc);
procedure Delete(Index: Integer);
property Items[Index: Integer]: TTruc read GetItem write SetItem; default;
end;
implementation
{ TTruc }
constructor TTruc.Create(pLibelle: string);
begin
libelle := pLibelle;
end; …Run Code Online (Sandbox Code Playgroud) 我想我需要在正确的方向上轻推:
我有两个相同数据类型的Tobjectlists,我想将这些连接到一个新列表中,list1将被复制(未修改),然后是list2(反向)
type
TMyListType = TobjectList<MyClass>
var
list1, list2, resList : TMyListtype
begin
FillListWithObjects(list1);
FillListWithOtherObjects(list2);
list2.reverse
//Now, I tried to use resList.Assign(list1, list2, laOr),
//but Tobjectlist has no Assign-Method. I would rather not want to
//iterate over all objects in my lists to fill the resList
end;
Run Code Online (Sandbox Code Playgroud)
delphi是否有任何内置函数将两个Tobjectlists合并为一个?
如果我们查看XERE2或XE3的TObjectList方法的在线帮助 ,我们会看到tobjectList可以访问binarysearch函数.但是如果我们尝试进入XE3,它甚至都不会编译.
对于该示例,sort函数也可用,但是这个编译.
欢迎任何想法.
示例代码:
unit FM_Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Contnrs, Vcl.CheckLst, System.Generics.Collections;
type
TTPRODData = class
private
FData1 : String;
FData2 : String;
FCount : Integer;
public
constructor Create; overload;
destructor Destroy; override;
end;
TTPRODDataList = class(TObjectList)
function GetItem(Index: Integer): TTPRODData;
procedure SetItem(Index: Integer; const Value: TTPRODData);
public
constructor Create; overload;
destructor Destroy; override;
property Items[Index: Integer]: TTPRODData read GetItem write SetItem; default;
procedure SortOnProductCode;
end;
TForm1 = …Run Code Online (Sandbox Code Playgroud) 我有一堆TCoordinates存储在TObjectList中.要更快地找到坐标,必须对列表进行排序.问题是iam交替搜索x和y.是否存在存储排序结果的方法,所以我不需要一次又一次地对列表进行排序.
unit uStackoverflowQuestion;
interface
uses
System.Generics.Collections, System.Generics.defaults;
type
TCoordinate = class(Tobject)
public
x: Integer;
y: Integer;
end;
TMultipleSortedList = class(TObjectlist<TCoordinate>)
public
// StoredSortingByX: List;
// StoredSortingByY: List;
procedure SortAndStoreByX;
procedure SortAndStoreByY;
end;
implementation
procedure TMultipleSortedList.SortAndStoreByX;
begin
// TODO -cMM: TMultipleSortedList.SortAndStoreByX default body inserted
end;
procedure TMultipleSortedList.SortAndStoreByY;
begin
// TODO -cMM: TMultipleSortedList.SortAndStoreByY default body inserted
end;
end.
Run Code Online (Sandbox Code Playgroud) delphi ×10
tobjectlist ×10
generics ×4
sorting ×3
delphi-2010 ×2
arrays ×1
class ×1
delphi-xe8 ×1
store ×1
tlist ×1