www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Initializing an associative array of struct

reply Denis <noreply noserver.lan> writes:
Hi,

I'm trying to combine a couple of general types (associative 
array, struct) in a compound data structure, but without success. 
Here is what I'm trying to achieve:

     "param" is a string variable
     "parameters[param].id" is an integer value
     "parameters[param].value" is a string value

param can be any of a fixed set of string values, all literals 
known at compile time.

parameters needs to be pre-populated with all of its keys during 
initialization, because they will be used to validate the param 
values that are read from a file (by checking if "param in 
parameters" is true).

I started with the following declarations:

     struct Parameter {
         int id;
         string value; }

     Parameter[string] parameters;
     string param;

But then I simply could not come up with a way to initialize the 
keys of parameters. I tried using assignments as well as enum, 
but always received either a compile or a runtime error. 
(Unfortunately the error messages did not enable me to find a 
solution.)

Note also that the defaults for id and value are fine (int and 
string defaults). But is it even possible to add the keys alone 
to parameters, without assigning something?

I would welcome a suggestion for how to initialize the keys of 
parameters. As there will be a couple dozen of the param string 
keys, a more succinct method would be preferable over a verbose 
one.

I realize that this is a very basic question, but I'm stumped!

Thank you in advance for your help.
Jun 13 2020
next sibling parent reply Kagamin <spam here.lot> writes:
string param="aa";
parameters[param]=Parameter();
in id=parameters[param].id;
Jun 14 2020
parent Kagamin <spam here.lot> writes:
that's
int id=parameters[param].id;
Jun 14 2020
prev sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Sunday, 14 June 2020 at 04:36:09 UTC, Denis wrote:

 Note also that the defaults for id and value are fine...
 I would welcome a suggestion for how to initialize the keys of 
 parameters. As there will be a couple dozen of the param string 
 keys, a more succinct method would be preferable over a verbose 
 one.
Param[string] parameters; string[] keys = [ "huh", "buh", "hrm", "pff", "err", "ack", "ugh", /* ... */ "zzz" ]; foreach (k; keys) parameters.require(k); https://dlang.org/spec/hash-map.html#inserting_if_not_present The `require` function, when called only with key, will insert default (.init) value for that key.
Jun 14 2020
parent reply Denis <noreply noserver.lan> writes:
 Kagamin:

On Sunday, 14 June 2020 at 07:16:18 UTC, Kagamin wrote:
 parameters[param]=Parameter();
I did not realize that you can use a type on the RHS of an assignment, but it is clear and succinct. This syntax will be very useful going forward -- thank you. Stanislav B: On Sunday, 14 June 2020 at 09:34:08 UTC, Stanislav Blinov wrote:
 string[] keys =
 [
 "huh", "buh", "hrm", "pff", "err", "ack", "ugh",
 /* ... */
 "zzz"
 ];
 foreach (k; keys)
     parameters.require(k);
This solves the problem of initializing the keys perfectly -- thank you. There does not appear to be a way to loop over the elements of an enum, so a string array does make the most sense as the initial container for the keys. I should add that your explanation for using `require` to perform the init is much more clear than the documentation!
 The `require` function, when called only with key, will insert 
 default (.init) value for that key.
I am just starting to learn D, and am missing so many pieces of the puzzle that I'm not yet able to always put "two and two" together myself. This kind of help really goes a long way. Again, my thanks to you both. Denis
Jun 14 2020
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/14/20 7:43 AM, Denis wrote:>  Kagamin:
 On Sunday, 14 June 2020 at 07:16:18 UTC, Kagamin wrote:
 parameters[param]=Parameter();
I did not realize that you can use a type on the RHS of an assignment,
Note that it's not just the type but with parenthesis after it. For example, Foo() default-constructs an object of Foo.
 There does not appear to be a way to loop over the elements of an enum,
There is std.traits.EnumMembers: import std.traits; enum Foo { abc, xyz } void main() { foreach (foo; EnumMembers!Foo) { // ... } } Ali
Jun 14 2020
parent Denis <noreply noserver.lan> writes:
On Sunday, 14 June 2020 at 15:44:04 UTC, Ali Çehreli wrote:
 On 6/14/20 7:43 AM, Denis wrote:>  Kagamin:
 On Sunday, 14 June 2020 at 07:16:18 UTC, Kagamin wrote:
 parameters[param]=Parameter();
I did not realize that you can use a type on the RHS of an
assignment, Note that it's not just the type but with parenthesis after it. For example, Foo() default-constructs an object of Foo.
Got it.
 There does not appear to be a way to loop over the elements
of an enum, There is std.traits.EnumMembers: import std.traits; enum Foo { abc, xyz } void main() { foreach (foo; EnumMembers!Foo) { // ... } }
Excellent. Because all of the keys are immutable strings and are known at compile time, enum seems like it should be well suited for the job. I will try this too. On a side note: I am working my way through your book, Ali. It really is very helpful for learning D, and for pointing out things that are not always clear from reading the documentation alone. I will admit, however, that I am not able to absorb all of the more subtle aspects yet. So this is an iterative process (read some, write code, re-read and read some more, write code, ...) Thank you for your help.
Jun 14 2020