Re: Search for, o/w create element for AA

2017-06-19 Thread Moritz Maxeiner via Digitalmars-d-learn

On Monday, 19 June 2017 at 15:19:19 UTC, Q. Schroll wrote:
I have to lookup x twice and it seems that there is no way 
around it. Can't I tell the AA to set a value for a given key 
if it doesn't already have one

 (1) with only one lookup, and
 (2) in a safe way?


AFAIK the builtin associate array implementation exposes neither 
such a function, nor other functions which you can use to 
assemble this, so no, you cannot do this with only one lookup 
(currently).
Though I can't see why it couldn't be added, seems fairly 
straight forward.
The best you can do with the builtin associative arrays right now 
is make sure that the `toHash` of your key type is cached.


Re: Search for, o/w create element for AA

2017-06-19 Thread Q. Schroll via Digitalmars-d-learn

On Monday, 19 June 2017 at 16:54:46 UTC, Ali Çehreli wrote:

On 06/19/2017 08:19 AM, Q. Schroll wrote:

Can't I tell the AA to set a value for a given key if it 
doesn't already

have one
 (1) with only one lookup, and
 (2) in a safe way?


aa.get(key, defaultValue)

  https://dlang.org/spec/hash-map.html#properties

Ali


aa.get returns the defaultValue if the key is not in the AA, but 
does not add the key-value pair (x, defaultValue) to the AA. I'd 
find it rather surprising if it did.


Re: Search for, o/w create element for AA

2017-06-19 Thread Ali Çehreli via Digitalmars-d-learn

On 06/19/2017 08:19 AM, Q. Schroll wrote:


Can't I tell the AA to set a value for a given key if it doesn't already
have one
 (1) with only one lookup, and
 (2) in a safe way?


aa.get(key, defaultValue)

  https://dlang.org/spec/hash-map.html#properties

Ali




Search for, o/w create element for AA

2017-06-19 Thread Q. Schroll via Digitalmars-d-learn

Trying to implement some random function I encountered this:

uint randFunc(uint x)
{
static uint[uint] vals;
if (auto r = x in vals) return *r;
return vals[x] = uniform!uint();
}

I have to lookup x twice and it seems that there is no way around 
it. Can't I tell the AA to set a value for a given key if it 
doesn't already have one

 (1) with only one lookup, and
 (2) in a safe way?
For the semantics, that should behave like this:

V set(K, V)(ref const(V)[const(K)] aa, auto ref const(K) key, 
lazy const(V) value)

{
if (auto valPtr = key in aa) return *valPtr;
// cast away const as initialization is okay:
return (cast() aa[key]) = value();
}

The function is dual to AA's get.

It would make it possible for an AA with const value type to have 
values added which is perfectly fine for arrays. All I have seen 
so far, one cannot safely add values to them as initialization 
and assignment cannot be distinguished.