digitalmars.D - associative array behavior
- novice2 (28/28) Dec 17 2004 Hi.
- Ben Hinkle (8/36) Dec 17 2004 accessed.
- Martin (12/60) Dec 17 2004 This is a very bad behavior and should be corrected. I know it is a feat...
- Stewart Gordon (11/16) Dec 17 2004 Do you mean you've weighed up the pros and cons? On practical grounds,
- Juanjo =?iso-8859-1?Q?=C1lvarez?= (5/8) Dec 18 2004 Can you please explain what are the cons of this behavior? I've listened
- Martin (58/66) Dec 18 2004 My point was, that exeption throwing is NOT nessesary or desirable. For ...
- MMM (5/73) Dec 19 2004 The question was: is it possible to owerload the 'in' operator and the f...
-
Stewart Gordon
(8/10)
Dec 20 2004
- Stewart Gordon (12/23) Dec 20 2004 Basically, that it takes an extra step to check whether an element is in...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (5/12) Dec 20 2004 The very bad behaviour is *not* that it returns an empty value.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (9/13) Dec 17 2004 Where is this documented, by the way ?
- Ben Hinkle (5/18) Dec 17 2004 The
- novice2 (8/56) Dec 18 2004 IMHO access to not existing items in associative array should throw exce...
- Martin (12/74) Dec 18 2004 It is very convinient that assosiative array returns a default value whe...
- novice2 (7/10) Dec 18 2004 Yes. I will be good, IMHO.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (14/36) Dec 18 2004 I don't think that it should output anything ?
- Think (7/45) Dec 19 2004 Yes but there should be a different switch for it. In most of my program...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (11/20) Dec 19 2004 On second thought, it should probably *not* throw exceptions.
- Russ Lewis (6/46) Dec 17 2004 This is, unfortunately, how the thing is designed to work.
- Garett Bass (6/31) Dec 17 2004 Based on the implementation of Java's Map, it seems more
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (7/13) Dec 18 2004 Reading the value creates the default initialized value...
- Regan Heath (5/34) Dec 19 2004 You can do this:
- Paul Bonser (7/47) Jan 15 2005 How about an isset() function, like in PHP? To check if there is a key
- Chris Sauls (6/10) Jan 16 2005 The following works currently:
- Paul Bonser (3/20) Jan 16 2005 And that doesn't add an empty item named "key"?
- Carotinho (5/8) Jan 16 2005 Yes, there was a thread about this behaviour, but I think it's been fixe...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (12/16) Jan 16 2005 The thread was about the fact that: if (myArray("key"))
- David L. Davis (78/98) Jan 16 2005 Paul Bonser: Just this weekend I was looking into how associative array ...
- Chris Sauls (27/47) Jan 17 2005 No it sure doesn't. To check for certain I tossed together this little ...
- Paul Bonser (3/8) Jan 17 2005 Well then, I retract my confused suggestion and am now happy. :) See,
- Kris (26/76) Jan 17 2005 The issue was never about 'in' ... it was about the read-only semantics ...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (9/27) Jan 17 2005 Hopefully, the current behaviour is a bug that will eventually be fixed
- Patrick Down (17/17) Jan 17 2005 Ruby does something with it hash types that I think is good.
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.
Dec 17 2004
"novice2" <novice2_member pathlink.com> wrote in message news:cput9j$2cu8$1 digitaldaemon.com...Hi. Associative array automatically add items, if it not existed but wasaccessed.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.This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable. -Ben
Dec 17 2004
This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one! Everything else should work as it is (for example if someone reads an nonexisting value then a default value is returned.) But reading must not actually create the element. Reading is reading and writing is writing. If we don't care that D is a logical, easy to use and easy to understand language, then why don't we all use Java or something else? Why spoil the D language? I truly hope you change it! (Ok for bakward compatiblity there can be a switch to switch between the on and another behavior.) In article <cpuuir$2e66$1 digitaldaemon.com>, Ben Hinkle says..."novice2" <novice2_member pathlink.com> wrote in message news:cput9j$2cu8$1 digitaldaemon.com...Hi. Associative array automatically add items, if it not existed but wasaccessed.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.This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable. -Ben
Dec 17 2004
Martin wrote:This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!Do you mean you've weighed up the pros and cons? On practical grounds, not just puristic ones? <snip>I truly hope you change it! (Ok for bakward compatiblity there can be a switch to switch between the on and another behavior.)<snip top of upside-down reply> I think D is still planning to be one standardised language, not two subtly different, mutually incompatible languages. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Dec 17 2004
On 2004-12-17, Stewart Gordon <smjg_1998 yahoo.com> wrote:Martin wrote:Can you please explain what are the cons of this behavior? 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...)This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
Dec 18 2004
My point was, that exeption throwing is NOT nessesary or desirable. For example if you have a file with words, you count the words and keep the result in an associative array. Let's say there was word 'fox' five times. Then array["fox"] equels 5. But let's say there was no word rabbit. Then array["rabbit"] equals 0. It's logical. Most of the time 0 means none. Most of the cases when I use associative arrays are such cases. (Mostly for me, not existing means "" and that is what it should be). PROGRAM.CONF: NAME="My program" MESSAGE="" VERSION="1.95" or PROGRAM.CONF: NAME="My program" VERSION="1.95" are the same. And my associative array CONF, the element CONF["MESSAGE"] should be "". Why should I count all the empty strings. eg PROGRAM.CONF: NAME="My program" MESSAGE="" MESSAGE1="" MESSAGE2="" MESSAGE3="" MESSAGE4="" MESSAGE5="something" MESSAGE6="" MESSAGE7="" VERSION="1.95" should be PROGRAM.CONF: NAME="My program" MESSAGE5="something" VERSION="1.95" And when an action occurs in my program, for example the user logs out then I do printf("%.*s",CONF["MESSAGE5"]); If this is specified then the user gets the message, if it isn't then the user gets nothing. (Ok here I could write the in check, but there are lots of situations that its very time consuming and makes code much uglyer.) Most of the time (not given)=(default value). This way I can program much faster and cleaner. But sometimes I need to know if the value was actually given or not. Then I use if("MESSAGE5" in CONF). But now, if I had done printf("%.*s",CONF["MESSAGE5"]); then everything is spoiled. I need to keep CONF and CONF_original where I do the 'in' clause only in CONF_original, but this is absurd!!! There is no need that the reading does create the key. There are opIndex and opIndexAssign. First I thought that maybe it is not possible to read on element without creating it. It is possible in D. So Walter please change it. CAN ANYONE TELL ME atleast one good reaseon why the reading of an element should create it? If for some reason Walter does not want to change it then I want to create my own associative arrays. I can use opIndex and opIndexAssign. But tell me, can I use something to overload 'in' for example if("string" in myArray). And how can I overload foreach? Thanks, Martin In article <cq1mtr$1vh1$1 digita ldaemon.com>, Juanjo =?iso-8859-1?Q?=C1lvarez?= says...On 2004-12-17, Stewart Gordon <smjg_1998 yahoo.com> wrote:Martin wrote:Can you please explain what are the cons of this behavior? 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...)This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
Dec 18 2004
The question was: is it possible to owerload the 'in' operator and the foreach one? Does anybody know? Thanks! In article <cq2etq$2m9v$1 digitaldaemon.com>, Martin says...My point was, that exeption throwing is NOT nessesary or desirable. For example if you have a file with words, you count the words and keep the result in an associative array. Let's say there was word 'fox' five times. Then array["fox"] equels 5. But let's say there was no word rabbit. Then array["rabbit"] equals 0. It's logical. Most of the time 0 means none. Most of the cases when I use associative arrays are such cases. (Mostly for me, not existing means "" and that is what it should be). PROGRAM.CONF: NAME="My program" MESSAGE="" VERSION="1.95" or PROGRAM.CONF: NAME="My program" VERSION="1.95" are the same. And my associative array CONF, the element CONF["MESSAGE"] should be "". Why should I count all the empty strings. eg PROGRAM.CONF: NAME="My program" MESSAGE="" MESSAGE1="" MESSAGE2="" MESSAGE3="" MESSAGE4="" MESSAGE5="something" MESSAGE6="" MESSAGE7="" VERSION="1.95" should be PROGRAM.CONF: NAME="My program" MESSAGE5="something" VERSION="1.95" And when an action occurs in my program, for example the user logs out then I do printf("%.*s",CONF["MESSAGE5"]); If this is specified then the user gets the message, if it isn't then the user gets nothing. (Ok here I could write the in check, but there are lots of situations that its very time consuming and makes code much uglyer.) Most of the time (not given)=(default value). This way I can program much faster and cleaner. But sometimes I need to know if the value was actually given or not. Then I use if("MESSAGE5" in CONF). But now, if I had done printf("%.*s",CONF["MESSAGE5"]); then everything is spoiled. I need to keep CONF and CONF_original where I do the 'in' clause only in CONF_original, but this is absurd!!! There is no need that the reading does create the key. There are opIndex and opIndexAssign. First I thought that maybe it is not possible to read on element without creating it. It is possible in D. So Walter please change it. CAN ANYONE TELL ME atleast one good reaseon why the reading of an element should create it? If for some reason Walter does not want to change it then I want to create my own associative arrays. I can use opIndex and opIndexAssign. But tell me, can I use something to overload 'in' for example if("string" in myArray). And how can I overload foreach? Thanks, Martin In article <cq1mtr$1vh1$1 digita ldaemon.com>, Juanjo =?iso-8859-1?Q?=C1lvarez?= says...On 2004-12-17, Stewart Gordon <smjg_1998 yahoo.com> wrote:Martin wrote:Can you please explain what are the cons of this behavior? 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...)This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
Dec 19 2004
MMM wrote:The question was: is it possible to owerload the 'in' operator and the foreach one?<snip top of upside-down reply> in - not yet foreach - look up opApply in the docs. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Dec 20 2004
Juanjo Álvarez wrote:On 2004-12-17, Stewart Gordon <smjg_1998 yahoo.com> wrote:Basically, that it takes an extra step to check whether an element is in before looking it up.Martin wrote:Can you please explain what are the cons of this behavior?This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!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.
Dec 20 2004
Stewart Gordon wrote: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 ? --andersBasically, that it takes an extra step to check whether an element is in before looking it up.Can you please explain what are the cons of this behavior?This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
Dec 20 2004
Ben Hinkle wrote:This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable.Where is this documented, by the way ? (Couldn't find it on the page about Associative Arrays: http://www.digitalmars.com/d/arrays.html#associative ?) I guess the default initializer is used for clearing the entry that one tries to access ? (When I tested, it set the values of strings to "" and integers to 0) Too bad that "in" still returns bit, on DMD 0.102 (GDC). --anders
Dec 17 2004
"Anders F Björklund" <afb algonet.se> wrote in message news:cpv4vd$2ll9$1 digitaldaemon.com...Ben Hinkle wrote:TheThis is how it is documented to work. The precedent is C++'s map class.thatalternative is to throw an exception and my guess for why it doesn't isHmm. I guess I was mistaken. I can't find it either. sorry about that!maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable.Where is this documented, by the way ? (Couldn't find it on the page about Associative Arrays: http://www.digitalmars.com/d/arrays.html#associative ?)I guess the default initializer is used for clearing the entry that one tries to access ? (When I tested, it set the values of strings to "" and integers to 0) Too bad that "in" still returns bit, on DMD 0.102 (GDC). --anders
Dec 17 2004
IMHO access to not existing items in associative array should throw exception "Out of bounds", like to access to not existing items in normal arrays. IMHO auto creating not existing items is confuse. It is bad side effect. For me disabling autocreating will have no pros (?) and some cons (better error detection). good luck novice2. In article <cpuuir$2e66$1 digitaldaemon.com>, Ben Hinkle says..."novice2" <novice2_member pathlink.com> wrote in message news:cput9j$2cu8$1 digitaldaemon.com...Hi. Associative array automatically add items, if it not existed but wasaccessed.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.This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable. -Ben
Dec 18 2004
It is very convinient that assosiative array returns a default value when a non-existing key is adressed. I mainly use char [][char[]] type arrays. Most time it is only the value that it is interesting and it is very good that (not set)="" When I really whant to know if the value is not set or set to "" then I use the in clause. But now reading spoils it. I THINK THAT READING MUST NOT CREATE A NEW KEY. READING IS READING WRITING IS WRITING. My suggestion is that reading should still return a default value but writing should not create the new key! What do you think? In article <cq1343$1duk$1 digitaldaemon.com>, novice2 says...IMHO access to not existing items in associative array should throw exception "Out of bounds", like to access to not existing items in normal arrays. IMHO auto creating not existing items is confuse. It is bad side effect. For me disabling autocreating will have no pros (?) and some cons (better error detection). good luck novice2. In article <cpuuir$2e66$1 digitaldaemon.com>, Ben Hinkle says..."novice2" <novice2_member pathlink.com> wrote in message news:cput9j$2cu8$1 digitaldaemon.com...Hi. Associative array automatically add items, if it not existed but wasaccessed.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.This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable. -Ben
Dec 18 2004
My suggestion is that reading should still return a default value but writing should not create the new key!Yes. I will be good, IMHO. I use char[char[]] too, and after first debug printf i loose information about was originally key exist or it was autoinserted.What do you think?IMHO autoinserting should be disabled. About result of read non existed key: for me, any of two variants appropriate: return default value or throw exception.
Dec 18 2004
Ben Hinkle wrote:It just looks like a bug in the D compiler ?Associative array automatically add items, if it not existed but was accessed.This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable.import std.stdio; void main() { char[][char[]] hash; hash["this"]; hash["looks"]; hash["like"]; hash["a"]; hash["bug"]; foreach(char[] str; hash.keys) writefln(str); }I don't think that it should output anything ? Surely it is not intended that I need to write:("key" in hash ? hash["key"] : "")just to avoid accidently setting it when reading ? I'm fine with it *returning* a zero/null value. Since arrays are always being initialized with the default initializer, it actually makes sense. Just don't think that it should be *adding* one ? Like someone suggested, maybe it should be treated as out of bounds ? Throw exceptions in -debug mode ? (just as with the regular indexed arrays, that is: ArrayBoundsError exceptions being thrown at runtime) --anders
Dec 18 2004
Like someone suggested, maybe it should be treated as out of bounds ? Throw exceptions in -debug mode ?Yes but there should be a different switch for it. In most of my programs I relay on returning a default value, if element does not exist. But some people may need to test their programs so this option would be needed. But this option sholdn't be default or else I still have to write ("key" in hash ? hash["key"] : "") just for avoining the exception. In article <cq2h5u$2n99$1 digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...Ben Hinkle wrote:It just looks like a bug in the D compiler ?Associative array automatically add items, if it not existed but was accessed.This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable.import std.stdio; void main() { char[][char[]] hash; hash["this"]; hash["looks"]; hash["like"]; hash["a"]; hash["bug"]; foreach(char[] str; hash.keys) writefln(str); }I don't think that it should output anything ? Surely it is not intended that I need to write:("key" in hash ? hash["key"] : "")just to avoid accidently setting it when reading ? I'm fine with it *returning* a zero/null value. Since arrays are always being initialized with the default initializer, it actually makes sense. Just don't think that it should be *adding* one ? Like someone suggested, maybe it should be treated as out of bounds ? Throw exceptions in -debug mode ? (just as with the regular indexed arrays, that is: ArrayBoundsError exceptions being thrown at runtime) --anders
Dec 19 2004
Think wrote:On second thought, it should probably *not* throw exceptions. An associative array doesn't really have any bounds per se... Languages like Perl don't need to separate between the two, since e.g. 0 and undef are different. But in D it's 0 and 0, (*) so you still need "in" to check if it really was set to zero... (in case you care about it, most programs wouldn't I suppose ?) But having it throw exceptions is probably just as annoying as having it write things to the A.A. when just reading, I agree. --anders *. For int[type] dictionaries, that is. (any non-reference AA)Like someone suggested, maybe it should be treated as out of bounds ? Throw exceptions in -debug mode ?Yes but there should be a different switch for it. In most of my programs I relay on returning a default value, if element does not exist. But some people may need to test their programs so this option would be needed. But this option sholdn't be default or else I still have to write ("key" in hash ? hash["key"] : "") just for avoining the exception.
Dec 19 2004
This is, unfortunately, how the thing is designed to work. Look at <expr> in <assoc_array> which returns null if the element doesn't exist, and a pointer to the element otherwise. 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.
Dec 17 2004
Based on the implementation of Java's Map, it seems more reasonable to me that arr["key"] should return null in the printf() example provided. How can reading the value create a value, and what value is created? After the printf(), does arr["key"] == null? This sure looks like a bug to me.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
Dec 17 2004
Garett Bass wrote:Based on the implementation of Java's Map, it seems more reasonable to me that arr["key"] should return null in the printf() example provided. How can reading the value create a value, and what value is created?Reading the value creates the default initialized value... i.e. "" for strings and 0 for integers (see the type list)After the printf(), does arr["key"] == null? This sure looks like a bug to me.Both in the printf and afterwards, the key becomes set. Only ("key" in arr) checks it, without modifying it too. I also think it's a bug. (it should return null, not set it!) --anders
Dec 18 2004
On Fri, 17 Dec 2004 15:17:07 +0000 (UTC), novice2 <novice2_member pathlink.com> 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.You can do this: item = "foo" in arr; Regan
Dec 19 2004
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.
Jan 15 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: -- Chris S
Jan 16 2005
Chris Sauls wrote:In article <cscvje$10aa$1 digitaldaemon.com>, Paul Bonser says...And that doesn't add an empty item named "key"? -PIBHow 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: -- Chris S
Jan 16 2005
Hi! Paul Bonser wrote:And that doesn't add an empty item named "key"? -PIBYes, there was a thread about this behaviour, but I think it's been fixed with latest version. I'm going to verify. Carotinho
Jan 16 2005
Carotinho wrote: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 --andersAnd 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.
Jan 16 2005
In article <csek55$2kef$1 digitaldaemon.com>, Paul Bonser says...Chris Sauls wrote: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. :) 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!"In article <cscvje$10aa$1 digitaldaemon.com>, Paul Bonser says...And that doesn't add an empty item named "key"? -PIBHow 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: -- Chris S
Jan 16 2005
In article <csek55$2kef$1 digitaldaemon.com>, Paul Bonser says...Chris Sauls wrote: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); }In article <cscvje$10aa$1 digitaldaemon.com>, Paul Bonser says...And that doesn't add an empty item named "key"? -PIBHow 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: -- Chris S
Jan 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 SaulsWell then, I retract my confused suggestion and am now happy. :) See, that smiley means I'm happy! -PIB
Jan 17 2005
The issue was never about 'in' ... it was about the read-only semantics of foo = myAA ['key']; if (foo) .. which actually modifies the 'myAA' with an empty key, if the entry did not exist prior to the read operation. Of course, this means that your code will break the next time this key is used (since there's now a bogus entry present). Question: if you performed a read operation on any other kind of array, would you expect the content to be modified? If you read from a file, would you expect the file-length the change? To say that this AA behavior departs from convention would be something of an understatement. It used to be that two hash-table lookups were needed to retrieve an entry, when one wished to avoid this bizzare and contrary behavior. Recently, Walter removed the necessity for the two lookups ... I'd call that a band-aid on a kludge. But that's just my opinion. Yes, it is nice having AA as part of the language core. Yes, it is convenient to avoid a cast from Object to the class type contained. Yes, there is some value in having a single AA container for both classes and native types. The price for this, in Walter's apparent view, is to break one of the most fundamental rules regarding read-only behavior (using AA purely as an rValue, treats it like an lValue also). I'd say that's a rather high price to pay -- I mean, it's only an associative array -- not the failover system for a nuclear reactor ... why introduce, in the core language, such a sneaky mechanism to break seemingly valid code? http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.dtl/124 In article <csfsgn$q3s$1 digitaldaemon.com>, Chris Sauls says...In article <csek55$2kef$1 digitaldaemon.com>, Paul Bonser says...Chris Sauls wrote: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); }In article <cscvje$10aa$1 digitaldaemon.com>, Paul Bonser says...And that doesn't add an empty item named "key"? -PIBHow 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: -- Chris S
Jan 17 2005
Kris wrote:Question: if you performed a read operation on any other kind of array, would you expect the content to be modified? If you read from a file, would you expect the file-length the change? To say that this AA behavior departs from convention would be something of an understatement.Hopefully, the current behaviour is a bug that will eventually be fixed and not a broken design? (not that it really matters in the meantime...) Unfortunately, it seems to work as intended:/************************************************* * Get pointer to value in associative array indexed by key. * Add entry for key if it is not already there. */ void *_aaGet(aaA*[] *aa, TypeInfo keyti, int valuesize, ...)versus/************************************************* * Determine if key is in aa. * Returns: * null not in aa * !=null in aa, return pointer to value */ void* _aaIn(aaA*[] aa, TypeInfo keyti, ...)Which means that currently you must use "in" with associative arrays, just as you must use "is" when comparing object pointers for identity. I still don't get *why* it's a good idea to create it, if it is missing? --anders
Jan 17 2005
Ruby does something with it hash types that I think is good. The constructor of the hash takes a function that provides the default behaviour when a key is not found. Associative arrays in D do not have constructors but it could be an attribute. // throw exception int[char[]] theMap; theMap.onKeyNotFound = delegate(int[char[]] map, char[] key) { throw KeyNotFoundError(); } // return default value int[char[]] theMap; theMap.onKeyNotFound = delegate(int[char[]] map, char[] key) { return 0; } // Add it to the assoc array int[char[]] theMap; theMap.onKeyNotFound = delegate(int[char[]] map, char[] key) { map[key] = 0; return 0; }
Jan 17 2005