Thread overview
anonymous static array
Mar 21, 2012
Stephan
Mar 21, 2012
David
Mar 21, 2012
Jesse Phillips
Mar 21, 2012
Vijay Nayar
Mar 21, 2012
bearophile
Mar 21, 2012
H. S. Teoh
Mar 21, 2012
Stephan
March 21, 2012
Hi,

I have an associative array with strings as keys and static arrays as values. When I access a new key, it gives me Range Error, so I think I should initialise the associative array, but how?

here is the code that fails:

int[100][string] counts;
counts["some_key"][20]++;
// core.exception.RangeError@freqSpec(26): Range violation


Thanks,

Stephan


March 21, 2012
Am 21.03.2012 11:51, schrieb Stephan:
> Hi,
>
> I have an associative array with strings as keys and static arrays as
> values. When I access a new key, it gives me Range Error, so I think I
> should initialise the associative array, but how?
>
> here is the code that fails:
>
> int[100][string] counts;
> counts["some_key"][20]++;
> // core.exception.RangeError@freqSpec(26): Range violation
>
>
> Thanks,
>
> Stephan
>

You can (or even have to?) do it in a static ctor.
March 21, 2012
On Wednesday, 21 March 2012 at 10:51:05 UTC, Stephan wrote:
> Hi,
>
> I have an associative array with strings as keys and static arrays as values. When I access a new key, it gives me Range Error, so I think I should initialise the associative array, but how?
>
> here is the code that fails:
>
> int[100][string] counts;
> counts["some_key"][20]++;
> // core.exception.RangeError@freqSpec(26): Range violation
>
>
> Thanks,
>
> Stephan

    int[100][string] counts;
    int[100] a;
    counts["some_key"] = a;
    counts["some_key"][20]++;

March 21, 2012
Jesse's solution is correct, but I thought I'd throw in a
comment or two.

You are correct that the associative array is uninitialized
by default, and that you must initialize it.  For very small
static arrays, a simple array literal like [1, 2, 3] would
suffice, but for larger arrays, this is a pain.

Here you can take advantage of the ".init" property that every
data-type has in D.  For example, "float.init" is "NaN".  Static
arrays are a unique type (the type includes the size), and it
has a ".init" property as well.  Due to syntax constraints,
you must place the type in parenthesis to prevent the square
brackets from messing things up.

So instead of creating a temporary variable, you can do this:

void main() {
  int[100][string] bob;
  bob["happy"] = (int[100]).init;
  bob["happy"][20] = 3;
  assert(bob["happy"][20] == 3)
}

Have a good one,

 - Vijay

On Wed, 21 Mar 2012, Jesse Phillips wrote:

> On Wednesday, 21 March 2012 at 10:51:05 UTC, Stephan wrote:
>> Hi,
>> 
>> I have an associative array with strings as keys and static arrays as values. When I access a new key, it gives me Range Error, so I think I should initialise the associative array, but how?
>> 
>> here is the code that fails:
>> 
>> int[100][string] counts;
>> counts["some_key"][20]++;
>> // core.exception.RangeError@freqSpec(26): Range violation
>> 
>> 
>> Thanks,
>> 
>> Stephan
>
>    int[100][string] counts;
>    int[100] a;
>    counts["some_key"] = a;
>    counts["some_key"][20]++;
>
>
March 21, 2012
Jesse Phillips:

>     int[100][string] counts;
>     int[100] a;
>     counts["some_key"] = a;
>     counts["some_key"][20]++;

Someone is currently trying to improve/fix AAs, this seems a
problem that is worth trying removing.

Bye,
bearophile
March 21, 2012
On Wed, Mar 21, 2012 at 04:15:18PM +0100, bearophile wrote:
> Jesse Phillips:
> 
> >    int[100][string] counts;
> >    int[100] a;
> >    counts["some_key"] = a;
> >    counts["some_key"][20]++;
> 
> Someone is currently trying to improve/fix AAs, this seems a problem that is worth trying removing.
[...]

That would be me. :-)

This is an interesting, and very important, issue. Currently, the language translates counts["some_key"][20] into:

	counts.opIndex("some_key").opIndexUnary!"++"(20)

The problem is that the first opIndex throws a RangeError if "some_key" doesn't exist in the AA. This makes sense (in a way) because if you write something like

	auto x = counts["some_key"];

which translates to:

	auto x = counts.opIndex("some_key");

and "some_key" doesn't exist, then it *should* throw. But if you're chaining the call in order to perform an operation on it, then it shouldn't throw, but instead it should behave like opIndexAssign.

So really, if you have a chain of indexing operations like this:

	a[b][c][d]++

then the final ++ should cause the entire series of opIndex operations to be translated differently. Perhaps there should be an opIndexCreate which is like opIndex except that if the entry is not found it gets created with the default value. So the above should translate to:

	a.opIndexCreate(b).opIndexCreate(c).opIndexUnary!"++"(d)

Indeed, any operation at all, not just ++, should cause the chain of lookups to switch to opIndexCreate() instead of opIndex, for example:

	a[b][c][d] = 1

should become:

	a.opIndexCreate(b).opIndexCreate(c).opIndexAssign(1,d)


T

-- 
Today's society is one of specialization: as you grow, you learn more and more about less and less. Eventually, you know everything about nothing.
March 21, 2012
Thanks everyone. OK, so a temporary variable seems to be the most obvious workaround, thanks Jesse. Thanks also to the others in pointing out this issue.

All the best,

Stephan


On Wednesday, 21 March 2012 at 14:19:03 UTC, Jesse Phillips wrote:
> On Wednesday, 21 March 2012 at 10:51:05 UTC, Stephan wrote:
>> Hi,
>>
>> I have an associative array with strings as keys and static arrays as values. When I access a new key, it gives me Range Error, so I think I should initialise the associative array, but how?
>>
>> here is the code that fails:
>>
>> int[100][string] counts;
>> counts["some_key"][20]++;
>> // core.exception.RangeError@freqSpec(26): Range violation
>>
>>
>> Thanks,
>>
>> Stephan
>
>     int[100][string] counts;
>     int[100] a;
>     counts["some_key"] = a;
>     counts["some_key"][20]++;