www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - anonymous static array

reply "Stephan" <ss27 sanger.ac.uk> writes:
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
Mar 21 2012
next sibling parent David <d dav1d.de> writes:
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.
Mar 21 2012
prev sibling parent reply "Jesse Phillips" <jessekphillips+D gmail.com> writes:
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]++;
Mar 21 2012
next sibling parent Vijay Nayar <vnayar wgen.net> writes:
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]++;
Mar 21 2012
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Mar 21 2012
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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.
Mar 21 2012
prev sibling parent "Stephan" <ss27 sanger.ac.uk> writes:
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]++;
Mar 21 2012