I tend to forget there is a record intialiser TPair.Create(Key, Value) – via: delphi – TDictionary populated during create example code – Stack Overflow
Posted by jpluimers on 2018/09/18
I tend to forget that since TPair
– introduced in Delphi 2009 – has had a TPair.Create(Key, Value)
record initialiser since Delphi 2010, though only fully documented since Delphi XE4:
- [WayBack] Delphi 2009: Generics.Collections.TPair Record – no Create constructor
- [Archive.is] Generics.Collections.TPair – RAD Studio 2010 VCL Reference – only Pascal documentation if the Create intisialiser
- [Archive.is] System.Generics.Collections.TPair.Create – XE2 API Documentation – only C++ documentation
- [Archive.is] System.Generics.Collections.TPair.Create – RAD Studio XE4 API Documentation – added Pascal documentation to the C++ documentation
With some spart short methods, Cosmin Prund shows a really nice helper at [WayBack] delphi – TDictionary populated during create example code – Stack Overflow allowing a call like this:
with TDictHelper<Integer, string> do Dict := Make([P(1, 'one'), P(2, 'two')]);
His answer has all the details (including describing the pros and conse), so here is only the helper:
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;
–jeroen
rvelthuis said
Why is this not a class helper for TDictionary? Then you can do:
Dict := TDictionary.Make(etc...);
.rvelthuis said
Er…
Dict := TDictionary<Integer, string>.Make(...);
.jpluimers said
Someday, I will have time to research that. Right now, I need to put a lot of energy in my brother to coach/assist with his mental retardation issues.
It might be a lot of work to do something like this, as class helpers for generic classes are not possible: [WayBack] delphi – Class Helper for generic class? – Stack Overflow
sglienke said
Because you cannot write helpers for generic types – see https://quality.embarcadero.com/browse/RSP-10336
sglienke said
… in the meanwhile in .NET: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-initialize-a-dictionary-with-a-collection-initializer
rvelthuis said
Wow, just like in Objective-C. They got that syntax a few years ago.
jpluimers said
Cool!