You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi集合类型选择咨询:如何实现一键对应双值的字典结构?

嗨,我来帮你理清Delphi开发里的集合类型选择,还有键对应两个值的实现方案~

Delphi开发中集合类型的选择

不同的集合类型适用于不同的场景,这里给你梳理几个常用的:

  • 动态数组(TArray):适合顺序存储元素,末尾增删效率高,但中间位置的插入/删除需要移动元素。如果只是需要简单的有序存储、遍历,动态数组是轻量又好用的选择。
  • TList / TObjectList:比动态数组更灵活,支持任意位置的插入、删除操作。TObjectList还能自动管理对象的生命周期(当移除元素或列表销毁时自动释放对象),非常适合存储对象实例。
  • TSet:专门用于存储不重复的元素,并且能高效执行集合运算(交集、并集、差集),还能快速判断元素是否存在。比如存储用户的权限标签、去重后的ID列表,用TSet效率拉满。
  • TDictionary<TKey, TValue>:键值对存储的首选,通过键查找值的时间复杂度接近O(1),适合需要快速查找、映射关系的场景,比如用户ID到用户信息的映射。
实现键对应两个值的结构(类似TDictionary<TKey, TFirstValue, TSecondValue>)

Delphi标准库没有直接提供这种三泛型的字典,但有几种简单的实现方式:

方案1:自定义记录/类封装两个值

最直接的方式是把两个值打包成一个记录(或类),然后用普通的TDictionary<TKey, 自定义类型>:

type
  // 根据你的需求替换类型
  TUserInfoPair = record
    UserName: string;
    Age: Integer;
  end;

// 使用示例
var
  UserDict: TDictionary<Integer, TUserInfoPair>; // Key是用户ID
  InfoPair: TUserInfoPair;
begin
  UserDict := TDictionary<Integer, TUserInfoPair>.Create;
  try
    InfoPair.UserName := 'Alice';
    InfoPair.Age := 28;
    UserDict.Add(1001, InfoPair);
    
    // 读取值
    if UserDict.TryGetValue(1001, InfoPair) then
    begin
      ShowMessage(Format('用户名:%s,年龄:%d', [InfoPair.UserName, InfoPair.Age]));
    end;
  finally
    UserDict.Free;
  end;
end;

如果需要存储引用类型(比如动态创建的对象),可以把记录换成类,注意手动管理内存(或配合TObjectList的思路)。

方案2:用TPair<TFirst, TSecond>直接作为值

Delphi的System.Generics.Collections单元已经提供了TPair<TFirst, TSecond>类型,专门用来封装两个值,省得自己定义记录:

uses
  System.Generics.Collections;

var
  MyDict: TDictionary<string, TPair<string, Integer>>;
  ValuePair: TPair<string, Integer>;
begin
  MyDict := TDictionary<string, TPair<string, Integer>>.Create;
  try
    // 直接创建TPair实例存入字典
    MyDict.Add('Product001', TPair<string, Integer>.Create('笔记本电脑', 5999));
    
    // 读取值
    if MyDict.TryGetValue('Product001', ValuePair) then
    begin
      ShowMessage(Format('商品:%s,价格:%d', [ValuePair.Value1, ValuePair.Value2]));
    end;
  finally
    MyDict.Free;
  end;
end;

方案3:自定义泛型字典类(更直观的用法)

如果你的项目里经常需要这种键对应两个值的结构,可以封装一个自己的泛型字典,让调用更简洁:

uses
  System.Generics.Collections;

type
  TTwoValueDict<TKey, TVal1, TVal2> = class(TDictionary<TKey, TPair<TVal1, TVal2>>)
  public
    // 新增直接传两个值的Add方法
    procedure Add(const Key: TKey; const Val1: TVal1; const Val2: TVal2);
    // 新增直接返回两个值的TryGetValue方法
    function TryGetValue(const Key: TKey; out Val1: TVal1; out Val2: TVal2): Boolean;
  end;

procedure TTwoValueDict<TKey, TVal1, TVal2>.Add(const Key: TKey; const Val1: TVal1; const Val2: TVal2);
begin
  inherited Add(Key, TPair<TVal1, TVal2>.Create(Val1, Val2));
end;

function TTwoValueDict<TKey, TVal1, TVal2>.TryGetValue(const Key: TKey; out Val1: TVal1; out Val2: TVal2): Boolean;
var
  TempPair: TPair<TVal1, TVal2>;
begin
  Result := inherited TryGetValue(Key, TempPair);
  if Result then
  begin
    Val1 := TempPair.Value1;
    Val2 := TempPair.Value2;
  end;
end;

// 使用示例
var
  ProductDict: TTwoValueDict<string, string, Integer>;
  ProductName: string;
  ProductPrice: Integer;
begin
  ProductDict := TTwoValueDict<string, string, Integer>.Create;
  try
    // 直接传入两个值,不用手动创建TPair
    ProductDict.Add('Product002', '智能手机', 3999);
    
    // 直接获取两个值,更直观
    if ProductDict.TryGetValue('Product002', ProductName, ProductPrice) then
    begin
      ShowMessage(Format('商品:%s,价格:%d', [ProductName, ProductPrice]));
    end;
  finally
    ProductDict.Free;
  end;
end;

内容的提问来源于stack exchange,提问作者Newbie Tester

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:50:22