Best ways to declare associative arrays

XavierAP via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Mar 12 05:49:25 PDT 2017


On Sunday, 12 March 2017 at 07:58:40 UTC, helxi wrote:
>
> string[string] change(ref string[string] arg_array){
> 	//..
> 	arg_array["first"] = strip(readln());
> 	//..
> 	arg_array["second"] = strip(readln());
> 	//..
> 	return def;
> }

Nicholas clarified why your declaration was wrong, but there are 
several strange things in your code that you may want to 
re-think. Also it looks to me that an associative array is not 
the most appropriate type for what you want to do.

To call a function you just pass the names of the arguments, not 
their types. So simply change(test), NOT change(string[string] 
test)

arg_array is an in-out (ref) parameter, but change() returns 
another value of the same type, def, not defined in your code, 
and which you do not use in main(). I think you may be interested 
only in changing arg_array, so the signature could be instead: 
void change(ref ...)

What you seem to want from your associative array is to associate 
two strings, "first" and "second" with two values (strings from 
the user), and only two. An associate array is more flexible than 
that, which is bad, you want your code to restrict you away from 
errors. For example if you keep using an associative array you 
could at the end of change(): assert(arg_array.length == 2);

I wonder if it's not enough and better for you to use a plain 
array. Keys "first" and "second" are not more informative than 
numeric indices. You may also use the advantage that an array can 
be hard-typed as fixed-length if this is known at compile time 
(and if you don't declare it with new), so it restricts your code 
in the perfect way:

void change(ref string[2] arg_array) {
	arg_array[0] = strip(readln());
	arg_array[1] = strip(readln());
}
void main() {
	string[2] test;
	change(test);
}

Also another disadvantage of associative arrays is that they are 
not ordered, so if for example in main() you read through the 
values in test with a foreach loop, you may get the result in any 
order (second first, and first second is possible). A simple 
array will keep order 0, 1.

If you were so bummed about using 0-1 instead of "first"-"second" 
you could define:

enum lineKey :size_t {
	first = 0,
	second
}
void change(ref string[2] arg_array) {
	arg_array[lineKey.first ] = strip(readln());
	arg_array[lineKey.second] = strip(readln());
}

But at least to me it looks worse. As a programmer you already 
know that the first index is 0 and 1 comes next.


More information about the Digitalmars-d-learn mailing list