如何在 TList 中找到记录的索引?
How do I find the index of a record in a TList?
我正在尝试统计每个 ProductCode 在我的数据库中的使用次数。问题是,我不知道所有的代码是什么(或者可能会添加更多)。
我假设我可以使用带有值对(productCode 和计数)的 TList 来执行此操作(我试图将其视为来自 c# 的 List<> 等)
procedure myProc
type
TProductCodeCount = record
productCode : string;
count : integer;
end;
var
productCodes : TList<TProductCodeCount>;
newProductCodeCount : TProductCodeCount;
currProductCodeCount : TProductCodeCount;
currentProductCode : string;
productCodeIndex : integer;
begin
productCodes := TList<TProductCodeCount>.Create;
// Get my data set
// Loop through my data set
begin
currentProductCode := // value from the database ;
productCodeIndex := productCodes.indexOf(currentProductCode);
if productCodeIndex = -1 then
begin
newProductCodeCount.productCode := currentProductCode;
newProductCodeCount.count := 1;
productCodes.Add(newProductCodeCount)
end
else
begin
currProductCodeCount := productCodes.Extract(productCodeIndex);
currProductCodeCount.count := currProductCodeCount.count + 1'
productCodes.Delete(productCodeIndex);
productCodes.Add (currProductCodeCount);
end
end;
// Loop through my TList
begin
// do something with each productCode and count.
end
end;
这里有两个大问题。
- 我不确定如何编写比较代码以使 indexOf 工作(如果这对于记录类型的 TList 甚至是可能的
- 列表项的更新很笨拙。
如何进行比较?或者有更好的方法来完成这个吗?
您可以使用自定义比较器,您将在构建期间传递给 TList<T>
。
type
TProductCodeCountComparer = class(TComparer<TProductCodeCount>)
public
function Compare(const Left, Right: TProductCodeCount): Integer; override;
end;
function TProductCodeCountComparer.Compare(const Left, Right: TProductCodeCount): Integer;
begin
Result := CompareStr(Left.productCode, Right.productCode);
end;
var
Comparer: IComparer<TProductCodeCount>
Comparer := TProductCodeCountComparer.Create;
productCodes := TList<TProductCodeCount>.Create(Comparer);
您也可以就地创建比较器
productCodes := TList<TProductCodeCount>.Create(
TComparer<TProductCodeCount>.Construct(
function (const Left, Right: TProductCodeCount): Integer
begin
Result := CompareStr(Left.productCode, Right.productCode);
end));
要就地编辑记录,您可以使用 TList<T>.List
属性,它可以让您直接访问基础 TList<T>
数组,并使您能够直接修改列表中的记录:
var
productCodes: TList<TProductCodeCount>;
....
inc(productCodes.List[productCodeIndex].count);
TList<T>.List
属性 是在 XE3 中引入的,对于早期 Delphi 版本以下 class 扩展启用就地记录修改:
TXList<T> = class(TList<T>)
protected type
PT = ^T;
function GetPItem(index: Integer): PT;
public
property PItems[index: Integer]: PT read GetPItem;
end;
function TXList<T>.GetPItem(index: Integer): PT;
begin
Result := @FItems[index];
end;
var
productCodes: TXList<TProductCodeCount>;
....
inc(productCodes.PItems[productCodeIndex].count);
我正在尝试统计每个 ProductCode 在我的数据库中的使用次数。问题是,我不知道所有的代码是什么(或者可能会添加更多)。
我假设我可以使用带有值对(productCode 和计数)的 TList 来执行此操作(我试图将其视为来自 c# 的 List<> 等)
procedure myProc
type
TProductCodeCount = record
productCode : string;
count : integer;
end;
var
productCodes : TList<TProductCodeCount>;
newProductCodeCount : TProductCodeCount;
currProductCodeCount : TProductCodeCount;
currentProductCode : string;
productCodeIndex : integer;
begin
productCodes := TList<TProductCodeCount>.Create;
// Get my data set
// Loop through my data set
begin
currentProductCode := // value from the database ;
productCodeIndex := productCodes.indexOf(currentProductCode);
if productCodeIndex = -1 then
begin
newProductCodeCount.productCode := currentProductCode;
newProductCodeCount.count := 1;
productCodes.Add(newProductCodeCount)
end
else
begin
currProductCodeCount := productCodes.Extract(productCodeIndex);
currProductCodeCount.count := currProductCodeCount.count + 1'
productCodes.Delete(productCodeIndex);
productCodes.Add (currProductCodeCount);
end
end;
// Loop through my TList
begin
// do something with each productCode and count.
end
end;
这里有两个大问题。
- 我不确定如何编写比较代码以使 indexOf 工作(如果这对于记录类型的 TList 甚至是可能的
- 列表项的更新很笨拙。
如何进行比较?或者有更好的方法来完成这个吗?
您可以使用自定义比较器,您将在构建期间传递给 TList<T>
。
type
TProductCodeCountComparer = class(TComparer<TProductCodeCount>)
public
function Compare(const Left, Right: TProductCodeCount): Integer; override;
end;
function TProductCodeCountComparer.Compare(const Left, Right: TProductCodeCount): Integer;
begin
Result := CompareStr(Left.productCode, Right.productCode);
end;
var
Comparer: IComparer<TProductCodeCount>
Comparer := TProductCodeCountComparer.Create;
productCodes := TList<TProductCodeCount>.Create(Comparer);
您也可以就地创建比较器
productCodes := TList<TProductCodeCount>.Create(
TComparer<TProductCodeCount>.Construct(
function (const Left, Right: TProductCodeCount): Integer
begin
Result := CompareStr(Left.productCode, Right.productCode);
end));
要就地编辑记录,您可以使用 TList<T>.List
属性,它可以让您直接访问基础 TList<T>
数组,并使您能够直接修改列表中的记录:
var
productCodes: TList<TProductCodeCount>;
....
inc(productCodes.List[productCodeIndex].count);
TList<T>.List
属性 是在 XE3 中引入的,对于早期 Delphi 版本以下 class 扩展启用就地记录修改:
TXList<T> = class(TList<T>)
protected type
PT = ^T;
function GetPItem(index: Integer): PT;
public
property PItems[index: Integer]: PT read GetPItem;
end;
function TXList<T>.GetPItem(index: Integer): PT;
begin
Result := @FItems[index];
end;
var
productCodes: TXList<TProductCodeCount>;
....
inc(productCodes.PItems[productCodeIndex].count);