有没有一种简单的方法将TDictionary的内容复制到另一个TDictionary中?

16
有没有一种单一的方法或简便的方式可以将一个TDictionary的内容复制到另一个?假设我有以下声明:
type
  TItemKey = record
    ItemID: Integer;
    ItemType: Integer;
  end;
  TItemData = record
    Name: string;
    Surname: string;
  end;
  TItems = TDictionary<TItemKey, TItemData>;

var
  // the Source and Target have the same types
  Source, Target: TItems;
begin
  // I can't find the way how to copy source to target
end;

我希望能够将源内容完全复制到目标位置。有这样的方法吗?
谢谢!
4个回答

29

TDictionary有一个构造函数,允许您传入另一个集合对象,它将通过复制原始内容来创建新的对象。这是您要寻找的吗?

constructor Create(Collection: TEnumerable<TPair<TKey,TValue>>); overload;

所以你可以这样使用

Target := TItems.Create(Source);

Target会被创建为Source的复制品(或者至少包含Source中的所有元素)。


2

如果你想更进一步,这里有另一种方法:

type
  TDictionaryHelpers<TKey, TValue> = class
  public
    class procedure CopyDictionary(ASource, ATarget: TDictionary<TKey,TValue>);
  end;

...implementation...

{ TDictionaryHelpers<TKey, TValue> }

class procedure TDictionaryHelpers<TKey, TValue>.CopyDictionary(ASource,
  ATarget: TDictionary<TKey, TValue>);
var
  LKey: TKey;
begin
  for LKey in ASource.Keys do
    ATarget.Add(LKey, ASource.Items[ LKey ] );
end;

根据您对的定义,使用方式如下:

TDictionaryHelpers<TItemKey, TItemData>.CopyDictionary(LSource, LTarget);

我认为这样会更快:var Item: TPair; ... for Item in ASource do ATarget.Add(Item.Key, Item.Value); - TomCat500

0

我认为这应该可以解决问题:

var
  LSource, LTarget: TItems;
  LKey: TItemKey;
begin
  LSource := TItems.Create;
  LTarget := TItems.Create;
  try
    for LKey in LSource.Keys do 
      LTarget.Add(LKey, LSource.Items[ LKey ]);
  finally
    LSource.Free;
    LTarget.Free;
  end; // tryf
end;

你能解释一下为什么你要赋值 LNewKey := LKey 而不是在表达式 LTarget.Add(LKey, LSource.Items[LKey]) 中直接使用两次 Lkey 吗? - RobertFrank
我认为这样会更快:var Item: TPair; ... for Item in LSource do ATarget.Add(Item.Key, Item.Value); - TomCat500

0
构建一个新实例当赋值意图时可能会产生副作用,例如在其他地方无效的对象引用。通用方法可能无法深度复制引用类型。
我会选择一个更简单的方法:
unit uExample;

interface

uses
  System.Generics.Collections;

type 
  TStringStringDictionary = class(TDictionary<string,string>)
  public
    procedure Assign(const aSSD: TStringStringDictionary);
  end;

implementation

procedure TStringStringDictionary.Assign(const aSSD: TStringStringDictionary );
var
  lKey: string;
begin
  Clear;
  for lKey in aSSD.Keys do
    Add(lKey, aSSD.Items[lKey]); // Or use copy constructors for objects to be duplicated
end;

end.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接