December 20, 2004
Juanjo Álvarez wrote:
> On 2004-12-17, Stewart Gordon <smjg_1998@yahoo.com> wrote:
> 
>>Martin wrote:
>>
>>>This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
> 
> Can you please explain what are the cons of this behavior?

Basically, that it takes an extra step to check whether an element is in before looking it up.

> I've listened to the "if it can throw an exception it's slower" argument but I don't
> think that's a good one (against the cons, more difficult to understand,
> more dificult to debug, unwanted side effects for sure, not logical...)

One could debate whether looking up a non-existent AA key is an expected or unexpected condition.  But the current behaviour has its strengths:

- it works well in cases where no element is ever set to ValueType.init or can be considered equivalent to a non-existent element
- it makes it easy to do a sparse matrix

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
December 20, 2004
Stewart Gordon wrote:

>>>> This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
>>
>> Can you please explain what are the cons of this behavior?
> 
> Basically, that it takes an extra step to check whether an element is in before looking it up.

The very bad behaviour is *not* that it returns an empty value.
(that has it strengths, as you and others have pointed out...)

It's that it modifies the AA, when you just try to read a value ?

--anders
January 16, 2005
How about an isset() function, like in PHP? To check if there is a key set. Something like:

if (myArray.isset("key"))
	...

Just an idea.

-PIB

novice2 wrote:
> Hi.
> 
> Associative array automatically add items, if it not existed but was accessed.
> Small example:
> 
> /**************************/
> alias char[] string;
> 
> void main()
> {
> string[string] arr;
> 
> if("key" in arr)
> printf("key exist\n");
> else
> printf("key not exist\n");
> 
> printf("arr[key]=%.*s\n", arr["key"]);
> 
> if("key" in arr)
> printf("key exist\n");
> else
> printf("key not exist\n");
> }
> /**************************/
> 
> For DMD 0.109 this program print:
> 
> key not exist
> arr[key]=
> key exist
> 
> Item auto inserted after access to it.
> Is it feature or bug?
> If it is feature - it is very inconveniently.
> So i can't trust to 'in' operator.
> 
> Sorry, if a missed something.
> 
> 
January 16, 2005
In article <cscvje$10aa$1@digitaldaemon.com>, Paul Bonser says...
>How about an isset() function, like in PHP? To check if there is a key set. Something like:
>
>if (myArray.isset("key"))
>	...

The following works currently:
#
# if (("key" in myArray) == null)
#

-- Chris S


January 16, 2005
Chris Sauls wrote:
> In article <cscvje$10aa$1@digitaldaemon.com>, Paul Bonser says...
> 
>>How about an isset() function, like in PHP? To check if there is a key set. Something like:
>>
>>if (myArray.isset("key"))
>>	...
> 
> 
> The following works currently:
> #
> # if (("key" in myArray) == null)
> #
> 
> -- Chris S
> 
> 

And that doesn't add an empty item named "key"?

-PIB
January 16, 2005
Hi!

Paul Bonser wrote:
> And that doesn't add an empty item named "key"?
> 
> -PIB

Yes, there was a thread about this behaviour, but I think it's been fixed with latest version. I'm going to verify.

Carotinho

January 16, 2005
Carotinho wrote:

>>And that doesn't add an empty item named "key"?
> 
> Yes, there was a thread about this behaviour, but I think
> it's been fixed with latest version. I'm going to verify.

The thread was about the fact that: if (myArray("key"))
*will* add a new item (default init) for the "key" key.

The change in DMD 0.107 was that: ("key" in myArray)
now returns a pointer, instead of the old true/false:

http://www.digitalmars.com/d/changelog.html#new0107

Since there is no difference in D between null and false,
the following code should still work: if ("key" in myArray)

But reading the key means "or create it if it doesn't exist"
This could have been mentioned more, in the documentation:

http://www.digitalmars.com/d/arrays.html#associative

--anders
January 16, 2005
In article <csek55$2kef$1@digitaldaemon.com>, Paul Bonser says...
>
>Chris Sauls wrote:
>> In article <cscvje$10aa$1@digitaldaemon.com>, Paul Bonser says...
>> 
>>>How about an isset() function, like in PHP? To check if there is a key set. Something like:
>>>
>>>if (myArray.isset("key"))
>>>	...
>> 
>> 
>> The following works currently:
>> #
>> # if (("key" in myArray) == null)
>> #
>> 
>> -- Chris S
>> 
>> 
>
>And that doesn't add an empty item named "key"?
>
>-PIB

Paul Bonser: Just this weekend I was looking into how associative array work, and have discovered a few things that I'd like to share by modifying your code example a bit. Hopefully you will find it helpful. I created a few free functions to do the main work in your example, but really a "class" would be better suited to encapsulate your associative array with these functions, tis a lot more reuseable. :)

Just remove the "#"s to use:

# private import std.stdio;
#
# alias char[] string;
#
# void main()
# {
#     string[ string ] arr;
#
#     // before adding "key"
#     writefln( "\"key\" exist = %s",
#         ( isset( arr, "key" ) ? "true" : "false" ) );
#     writefln();
#
#     writefln( "adding \"key\" and \"key2\"" );
#     arr[ "key"  ] = "added a key";
#     arr[ "key2" ] = "added another key";
#     writefln( "number of entries in arr = %d", arr.length );
#     displayEntries( arr );
#
#     // after adding keys
#     writefln( "\"key\" exist = %s",
#         ( isset( arr, "key" ) ? "true" : "false" ) );
#     writefln();
#
#     writefln( "removing key2..." );
#     remove( arr, "key2" );
#     displayEntries( arr );
# }
#
# bool isset( in string[ string ] arr, in char[] sKey )
# {
#     if ( ( sKey in arr ) != null )
#         return true;
#     else
#         return false;
# }
#
# void remove( inout string[ string ] arr, in char[] sKey )
# {
#     delete arr[ sKey ];
# }
#
# void removeall( inout string[ string ] arr )
# {
#     foreach( char[] sKey; arr.keys )
#         delete arr[ sKey ];
# }
#
# void displayEntries( in string[ string ] arr )
# {
#     foreach( char[] sKey, char[] sValue; arr )
#         writefln( "sKey=\"%s\", sValue=\"%s\"", sKey, sValue );
# }

output:
C:\dmd>bin\dmd assocarray.d
C:\dmd\bin\..\..\dm\bin\link.exe assocarray,,,user32+kernel32/noi;

C:\dmd>assocarray
"key" exist = false

adding "key" and "key2"
number of entries in arr = 2
sKey="key", sValue="added a key"
sKey="key2", sValue="added another key"
"key" exist = true

removing key2...
sKey="key", sValue="added a key"

C:\dmd>
------------------------
David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
January 17, 2005
In article <csek55$2kef$1@digitaldaemon.com>, Paul Bonser says...
>
>Chris Sauls wrote:
>> In article <cscvje$10aa$1@digitaldaemon.com>, Paul Bonser says...
>> 
>>>How about an isset() function, like in PHP? To check if there is a key set. Something like:
>>>
>>>if (myArray.isset("key"))
>>>	...
>> 
>> 
>> The following works currently:
>> #
>> # if (("key" in myArray) == null)
>> #
>> 
>> -- Chris S
>> 
>> 
>
>And that doesn't add an empty item named "key"?
>
>-PIB

No it sure doesn't.  To check for certain I tossed together this little test. Compiled and ran with DMD 0.110 and found that in-expressions do /not/ add empty items.

-- Chris Sauls



module aatest;

import std.stdio;

void main() {
char[][char[]] map;
char[]* value;

writefln("\nStart");
writefln("map.length == ", map.length);

value = "foo" in map;
writefln("\nUsing 'in' the first time");
writefln("foo in map == ", value == null ? "null" : *value);
writefln("map.length == ", map.length);

map["foo"] = "abc";
value = "foo" in map;
writefln("\nAdding item, using 'in' the second time");
writefln("foo in map == ", value == null ? "null" : *value);
writefln("map.length == ", map.length);

delete map["foo"];
value = "foo" in map;
writefln("\nDeleting item, using 'in' the third time");
writefln("foo in map == ", value == null ? "null" : *value);
writefln("map.length == ", map.length);
}


January 17, 2005
> No it sure doesn't.  To check for certain I tossed together this little test.
> Compiled and ran with DMD 0.110 and found that in-expressions do /not/ add empty
> items.
> 
> -- Chris Sauls

Well then, I retract my confused suggestion and am now happy. :) See, that smiley means I'm happy!

-PIB