Delphi t在创建示例代码期间填充字典
是否有人在其构造函数中填充了Delphi t在创建示例代码期间填充字典,delphi,Delphi,是否有人在其构造函数中填充了t字典的示例代码?您需要调用接收集合的类型为TEnumerable的参数 例如,假设我们有TDictionary。然后我们可以将TEnumerable的一个实例传递给构造函数。这类事情的一个例子是 因此,如果您已经有一个字典实例,您可以创建另一个,并使用第一个实例的内容对其进行初始化: Dict2 := TDictionary<string, Integer>.Create(Dict1); Dict2:=TDictionary.Create(Dict1)
t字典的示例代码?您需要调用接收集合的类型为TEnumerable
的参数
例如,假设我们有TDictionary
。然后我们可以将TEnumerable
的一个实例传递给构造函数。这类事情的一个例子是
因此,如果您已经有一个字典实例,您可以创建另一个,并使用第一个实例的内容对其进行初始化:
Dict2 := TDictionary<string, Integer>.Create(Dict1);
Dict2:=TDictionary.Create(Dict1);
显然,您只需要一行程序,所以我尝试了一下,实现了一个TDictHelper
,它允许使用一行程序创建和填充字典
使用任何形式的一行程序初始化字典的问题是它需要成对的值,而我们没有传递这些值对所需的良好语法。例如,如果需要为添加到字典中的每对值使用TPair.Create(A,B)
语法,那么这将是一个难看的一行
我确实想出了几个好看的选择;第一个是这样使用的:
with TDictHelper<Integer, string> do
Dict := Make([P(1, 'one'), P(2, 'two')]);
这会管用,但会非常非常难看
由于将与
一起使用可能会有问题(特别是如果您想使用两种词典),因此我提供了一种替代语法;不幸的是,这一个无法扩展,它很快变得非常丑陋:
Dict := TDictHelper<Integer, string>.Make([1, 2], ['one', 'two']);
在下面的示例中,键和值的数组被传递给自定义构造函数。使用以下模式将键和值放置在同一数组中:key1、value1、key2、value2、…、keyN、valueN。数组必须包含偶数个项
unit MainUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Collections, System.Rtti;
type
TForm3 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
TMyDictionary<TK, TV> = class(TDictionary<TK,TV>)
constructor Create(const values: array of variant);
end;
var
Form3: TForm3;
extensions: TMyDictionary<string, integer>;
implementation
constructor TMyDictionary<TK, TV>.Create(const values: array of variant);
var
I: Integer;
k, v: TValue;
kt: TK;
vt: TV;
begin
inherited Create(Length(values) div 2);
I := Low(values);
while i <= High(values) do
begin
k := TValue.FromVariant(values[i]);
v := TValue.FromVariant(values[i + 1]);
kt := k.AsType<TK>;
vt := v.AsType<TV>;
Add(kt, vt);
Inc(I, 2);
end;
end;
{$R *.dfm}
begin
extensions := TMyDictionary<string, integer>.Create(['1', 1, '3', 3]);
OutputDebugString(PChar(IntToStr(extensions['1'])));
end.
单元主单元;
接口
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
控件、窗体、对话框、System.Generics.Collections、System.Rtti;
类型
TForm3=类别(TForm)
私有的
{私有声明}
公众的
{公开声明}
结束;
TMyDictionary=类(TDictionary)
构造函数创建(常量值:变量数组);
结束;
变量
表3:TForm3;
扩展:TMyDictionary;
实施
构造函数TMyDictionary.Create(常量值:变量数组);
变量
I:整数;
k、 v:TValue;
kt:TK;
vt:电视;
开始
继承的Create(长度(值)div 2);
I:=低(值);
虽然我可能会感到困惑,但我认为:构造函数Create(Collection:TEnumerable);超载;他告诉我,在create方法期间,我可以用多对数据填充TDictionary。我是否误读了符号?只有两个构造函数重载允许您在构造期间填充。它们都接收类型为TEnumerable
的类的实例。您可以编写一个helper函数来创建一个允许内联编码的函数。它与Python版本有很长的距离:Dictionary={'Foo':42,'Bar':666}
实际上,您甚至不能在这里编写帮助函数,因为您需要释放传递给构造函数的临时容器。所以,是的,这个班级的设计是反对你的。在这种情况下,其他一些容器库可能更灵活。我不知道,但我听到了很多关于Delphi spring库中容器的好消息。@David太糟糕了,它不需要一个IEnumerable
@David,正如我的回答所示,一个开放的成对数组很难以可读的方式实例化。这就是为什么我使用with
操作符,所以我可以使用helperP
类函数。Delphi中没有语法可以用一行程序来初始化记录,你需要调用一个构造函数。请注意,它从来不会精确地执行问题所要求的操作,即在其构造函数中填充dict。无论如何,当dict构造函数使用TEnumerable执行此操作时,它会调用AddOrSetValue,您可能希望在这里进行模拟。@David,我把这个问题看作是在询问一种填充TDictionary
的单行程序方法。当然,我可能错了。不,这很公平。我很高兴有一点创造性的解释。我的回答是直截了当的。你的值+1。
Dict := TDictHelper<Integer, string>.Make(TPair<Integer, string>.Create(1, 'one'), TPair<Integer, string>.Create(2, 'two'));
Dict := TDictHelper<Integer, string>.Make([1, 2], ['one', 'two']);
program Project25;
{$APPTYPE CONSOLE}
uses
SysUtils, Generics.Collections;
type
TDictHelper<Key, Value> = class
public
class function P(const K:Key; const V:Value): TPair<Key, Value>;
class function Make(init: array of TPair<Key, Value>): TDictionary<Key, Value>;overload;
class function Make(KeyArray: array of Key; ValueArray: array of Value): TDictionary<Key, Value>;overload;
end;
{ TDictHelper<Key, Value> }
class function TDictHelper<Key, Value>.Make(init: array of TPair<Key, Value>): TDictionary<Key, Value>;
var P: TPair<Key, Value>;
begin
Result := TDictionary<Key, Value>.Create;
for P in init do
Result.AddOrSetValue(P.Key, P.Value);
end;
class function TDictHelper<Key, Value>.Make(KeyArray: array of Key;
ValueArray: array of Value): TDictionary<Key, Value>;
var i:Integer;
begin
if Length(KeyArray) <> Length(ValueArray) then
raise Exception.Create('Number of keys does not match number of values.');
Result := TDictionary<Key, Value>.Create;
for i:=0 to High(KeyArray) do
Result.AddOrSetValue(KeyArray[i], ValueArray[i]);
end;
class function TDictHelper<Key, Value>.P(const K: Key;
const V: Value): TPair<Key, Value>;
begin
Result := TPair<Key, Value>.Create(K, V);
end;
// ============================== TEST CODE FOLLOWS
var Dict: TDictionary<Integer, string>;
Pair: TPair<Integer, string>;
begin
try
try
// Nice-looking but requires "with" and you can't work with two kinds of DictHelper at once
with TDictHelper<Integer, string> do
Dict := Make([P(1, 'one'), P(2, 'two')]);
// Use the array
for Pair in Dict do
WriteLn(Pair.Key, ' = ', Pair.Value);
Dict.Free;
// Passing the Keys and the Values in separate arrays; Works without "with" but it would
// be difficult to maintain for larger number of key/value pairs
Dict := TDictHelper<Integer, string>.Make([1, 2], ['one', 'two']);
// Use the array
for Pair in Dict do
WriteLn(Pair.Key, ' = ', Pair.Value);
Dict.Free;
except on E:Exception do
WriteLn(E.ClassName, #13#10, E.Message);
end;
finally ReadLn;
end;
end.
unit MainUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Collections, System.Rtti;
type
TForm3 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
TMyDictionary<TK, TV> = class(TDictionary<TK,TV>)
constructor Create(const values: array of variant);
end;
var
Form3: TForm3;
extensions: TMyDictionary<string, integer>;
implementation
constructor TMyDictionary<TK, TV>.Create(const values: array of variant);
var
I: Integer;
k, v: TValue;
kt: TK;
vt: TV;
begin
inherited Create(Length(values) div 2);
I := Low(values);
while i <= High(values) do
begin
k := TValue.FromVariant(values[i]);
v := TValue.FromVariant(values[i + 1]);
kt := k.AsType<TK>;
vt := v.AsType<TV>;
Add(kt, vt);
Inc(I, 2);
end;
end;
{$R *.dfm}
begin
extensions := TMyDictionary<string, integer>.Create(['1', 1, '3', 3]);
OutputDebugString(PChar(IntToStr(extensions['1'])));
end.