www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Creating an array of user-defined structs

reply brian <brian infinityplusb.com> writes:
So I have the below program:

import std.stdio;

/* defines my awesome struct */
struct testStruct
{
	string aa;
	string bb;
}

/* creates(?) an empty array of structs */
testStruct[int] testStructArray;

void main()
{	
	string a = "a";
	string b = "b";

/*make a new struct */
	auto newStruct = new testStruct;
/* populate the values for the struct */
	newStruct.aa = a.dup;
	newStruct.bb = b.dup;

	writeln(newStruct.aa);
/* oddly if I remove the write to "bb" line, the aa line gives an 
error above user access */
	writeln(newStruct.bb);

/* this errors, claiming something about a pointer?? */
	testStructArray[1] = newStruct;
}

Running this my output says:
Error: cannot implicitly convert expression (newStruct) of type 
testStruct* to testStruct

So I have a couple of questions:
1) I'm assuming by the error that line 23 defines a pointer 
rather than a ... not-pointer thing. I'm not sure why it is doing 
that, and would like some explanation please. :)
2) Is this the best way to do what I am trying to do, which is 
dynamically grow an array of user defined structs?

TIA
Brian
Aug 21 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 21 August 2016 at 23:28:14 UTC, brian wrote:
 /* creates(?) an empty array of structs */
 testStruct[int] testStructArray;
That's not actually an array per se, that is a key/value map where the keys are ints. So you can set values to it at any position in it but not append or do other traditional array operations. An ordinary array is defined with testStruct[] testStructArray; though what you have isn't necessarily wrong.
 	auto newStruct = new testStruct;
This is the cause of the pointer mismatch error - new struct returns a pointer to it. If you just want an ordinary struct you define it: testStruct newStruct; like that.
 	newStruct.aa = a.dup;
 	newStruct.bb = b.dup;
No need for the .dup there because strings aren't going to be changing under you anyway.
 1) I'm assuming by the error that line 23 defines a pointer 
 rather than a ... not-pointer thing. I'm not sure why it is 
 doing that, and would like some explanation please. :)
It is just how new works in D, it returns a reference. For structs, that means a pointer to it.
 2) Is this the best way to do what I am trying to do, which is 
 dynamically grow an array of user defined structs?
Either do a traditional array and copy struct values onto it or do an array of pointers and new them. Which option is bsed depends on the details of what you're doing.
Aug 21 2016
parent reply brian <brian infinityplusb.com> writes:
Thanks Adam.

Couple of follow up questions, if you don't mind:

On Sunday, 21 August 2016 at 23:37:38 UTC, Adam D. Ruppe wrote:
 testStruct[int] testStructArray;
That's not actually an array per se, that is a key/value map where the keys are ints.
I understand it's a map, but does my syntax not define an Associative Array?? https://dlang.org/spec/hash-map.html That's kinda what I wanted because I want to be able to look up the Structs by the value of int.
 Either do a traditional array and copy struct values onto it or 
 do an array of pointers and new them. Which option is bsed 
 depends on the details of what you're doing.
This was a simple example of what I wanted to illustrate the problem. What I probably want for my future program state is some sort of hash map, as I'll be using this "array" as a lookup table. So conceptually something like: userid | username | structs ---------------------------- 0001 | brian | structAboutBrian 0002 | john | structAboutJohn I probably want to be able to look up info using either userid, or username, but I can settle for one of them I'm creating the entries during execution of the program, so I have no idea how big the structure is going to be. So I wanted something dynamic. I'm a bit of a novice in terms of theoretical comp sci, so I'm not sure what data structure would be best suited to something like that, or how to implement. Happy to take advice. :)
Aug 21 2016
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 21 August 2016 at 23:57:27 UTC, brian wrote:
 I understand it's a map, but does my syntax not define an 
 Associative Array??
yeah, it is. If that's what you want, good!
 So I wanted something dynamic.
OK, then you should use pointers so you can have several references to the same object in different maps (so you can have one for ID, one for name, etc.). Just make it testStruct*[int] testStructArray; and then try compiling the rest basically as it is, newing the struct, it should work.
Aug 21 2016
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 21 August 2016 at 23:57:27 UTC, brian wrote:

 On Sunday, 21 August 2016 at 23:37:38 UTC, Adam D. Ruppe wrote:
 testStruct[int] testStructArray;
That's not actually an array per se, that is a key/value map where the keys are ints.
I understand it's a map, but does my syntax not define an Associative Array?? https://dlang.org/spec/hash-map.html That's kinda what I wanted because I want to be able to look up the Structs by the value of int.
Terminology wise, we distinguish between associative arrays (AA) and arrays. The former should never simply be called 'array', otherwise people will assume you are referring to either or both of foo[] (dynamic array/slice) or foo[N] (where N is an integer constant, a static array). Change your title to 'Creating an AA of user-defined structs' and the misunderstanding goes away.
Aug 21 2016
parent reply brian <brian infinityplusb.com> writes:
On Monday, 22 August 2016 at 06:19:00 UTC, Mike Parker wrote:
 Terminology wise, we distinguish between associative arrays 
 (AA) and arrays. The former should never simply be called 
 'array', otherwise people will assume you are referring to 
 either or both of foo[] (dynamic array/slice) or foo[N] (where 
 N is an integer constant, a static array). Change your title to 
 'Creating an AA of user-defined structs' and the 
 misunderstanding goes away.
That's a terribly confusing naming convention for beginners then! :P Is this D-specific terminology, or is this a more general convention that AA are not actually arrays? This might help my understanding of when to use or not use one or the other. :)
Aug 22 2016
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Monday, 22 August 2016 at 07:00:23 UTC, brian wrote:

 That's a terribly confusing naming convention for beginners 
 then! :P
 Is this D-specific terminology, or is this a more general 
 convention that AA are not actually arrays?
 This might help my understanding of when to use or not use one 
 or the other. :)
AA is an existing term and the concept is not specific to D (see the Wikipedia article [1]). Several other languages have them. An AA is quite a distinct data structure from an array. Whereas arrays hold their items directly and tend to be laid out sequentially in memory (though they don't have to be), AAs do not and are not -- they might have linked lists, red-black trees or other data structures holding the items under the hood, all requiring the allocation of special nodes to associate meta data with each item. Arrays are indexed with sequential integers, AAs can be indexed with any properly configured key. It's only the read/write syntax in D that's similar, i.e. foo[key], though it didn't have to be that way. Take the [] syntax away from an AA and you might end up with something like the Java HashMap/HashTable or the C++ std::unordered_map. The name almost certainly derives from the [] syntax. Because AAs and arrays distinct data structures (there are things you can do with one, but not the other), it's important to distinguish them in conversation. [1] https://en.wikipedia.org/wiki/Associative_array
Aug 22 2016
prev sibling parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Monday, 22 August 2016 at 07:00:23 UTC, brian wrote:
 On Monday, 22 August 2016 at 06:19:00 UTC, Mike Parker wrote:
 Terminology wise, we distinguish between associative arrays 
 (AA) and arrays. The former should never simply be called 
 'array', otherwise people will assume you are referring to 
 either or both of foo[] (dynamic array/slice) or foo[N] (where 
 N is an integer constant, a static array). Change your title 
 to 'Creating an AA of user-defined structs' and the 
 misunderstanding goes away.
That's a terribly confusing naming convention for beginners then! :P Is this D-specific terminology, or is this a more general convention that AA are not actually arrays? This might help my understanding of when to use or not use one or the other. :)
Listen to Mike. This is not specific to D and they are only arrays in name. I want to provide other examples because I think I come across this with other words in English. Where one thing uses the name of another, but there really isn't enough similarities that it would make sense to refer to them in the same bucket. In your case though it is similar to square vs rectangle. If you are trying to understand some properties about squares, you could talk about having a rectangle, but it is more helpful to be specific. Consider asking how to find the area of a rectangle, you'll get the answer "length * height" while asking to finding the area of a square you might get "length^2"
Aug 22 2016