D - associative arrays? how to use them?
- Ivan Senji (80/80) Mar 20 2004 I first have to say that i am sory for asking this question again!
- Manfred Nowak (6/7) Mar 20 2004 [...]
- Ivan Senji (4/11) Mar 20 2004 I didn't miss this.
- Manfred Nowak (10/11) Mar 20 2004 Because DigitalMars did not answer my questions, I consider it as a bug
- Ben Hinkle (12/19) Mar 20 2004 opCmp needs to have the same signature as in object.d:
- Ivan Senji (5/24) Mar 20 2004 Thanks!
- Stewart Gordon (39/42) Mar 22 2004 That explains something, but I still think Object.opCmp is silly.
- Ivan Senji (8/49) Mar 22 2004 I agree with you that this is a strange bahaviour of D, i realy can't
- Stewart Gordon (17/23) Mar 23 2004 - toHash - to decide which hash slot to look in
I first have to say that i am sory for asking this question again! I tried for a long time but i just can't understand how associative arrays work? First a simple example: (this works) int[char[]] assoc; assoc["ivan"]=1; //assoc.length == 1 assoc["ira"]=2; //assoc.length == 2 assoc["ivan"]=3; //assoc.length == 2 char[] name; name~= "i"; name~= "v"; name~= "a"; name~= "n"; char[] name2; name2~= "i"; name2~= "v"; name2~= "a"; name2~= "n"; char[] name3 = "_ivan_"[1..5]; assoc[name]=4; //assoc.length == 2 assoc[name2]=5; //assoc.length == 2 assoc[name3]=6; //assoc.length == 2 This example works the way i expect it to work: when i insert the same element again the length doesn't increase! Example 2: (associative array with class key) class Point { int x,y; this(int x,int y) { this.x=x; this.y=y; } int opEquals(Point x) { if(this.x == x.x && this.y == x.y)return 1; else return 0; } uint toHash() { return this.x + this.y; } int opCmp(in Point x) { if(this.x < x.x){return -1;} if(this.x > x.x){return 1;} if(this.y < x.y){return -1;} if(this.y >= x.y){return 1;} } } int main(char [] [] args) { int[Point] assoc2; Point t = new Point(6,7); assoc2[new Point(1,2)]=1; //assoc2.length==1 assoc2[new Point(1,2)]=2; //assoc2.length==2 !!žbut the same point(1,2) is inserted assoc2[new Point(6,7)]=3; //assoc2.length==3 assoc2[t]=4; //assoc2.length==4 !! the Point(6,7) is allready in the associative array! but length increases assoc2[t]=5; //assoc2.length==4 } Is this the way it should work? When i insert the element that is already in the array it is inserted again? Walter said that asoociative array uses toHash() and opCmp() when the values returned by toHash() are different but this is not true! opCmp is never called! It looks to me that the associative array is only looking at the adress of the inserted object, but if i wanted to keep track of instances of objects using associative array i can always use associative array where index is a pointer to an object! I want to keep track of different objects (by different i mean opEquals or opCmp-diffrent) and is this possible with associative arrays? I tried using structs as a key but i get a compiler error: Internal error: ..\ztc\cod1.c 1641 Help me please! I like the idea of associative array a lot but i would like to know how to use them with class keys, and is it possible?
Mar 20 2004
Ivan Senji wrote: [...]Example 2: (associative array with class key)[...] Did you miss <c0vetu$167g$1 digitaldaemon.com> = http://www.digitalmars.com/drn-bin/wwwnews?D/24119 ? So long!
Mar 20 2004
"Manfred Nowak" <svv1999 hotmail.com> wrote in message news:c3ht3b$r55$1 digitaldaemon.com...Ivan Senji wrote: [...]I didn't miss this. So is this behaviour of associative arrays a bug or what?Example 2: (associative array with class key)[...] Did you miss <c0vetu$167g$1 digitaldaemon.com> = http://www.digitalmars.com/drn-bin/wwwnews?D/24119 ? So long!
Mar 20 2004
Ivan Senji wrote: [...]So is this behaviour of associative arrays a bug or what?Because DigitalMars did not answer my questions, I consider it as a bug and I am content with the workaround. However the status is open as far as I know. If you want to see it as a bug, then try if the workaround serve your understanding. If you do not want to see it as a bug, then may be, that someone is able to explain it to you. So long!
Mar 20 2004
int opCmp(in Point x) { if(this.x < x.x){return -1;} if(this.x > x.x){return 1;} if(this.y < x.y){return -1;} if(this.y >= x.y){return 1;} }opCmp needs to have the same signature as in object.d: int opCmp(Object obj) { Point x = cast(Point)obj; if (x is null) return super.opCmp(xo); if(this.x < x.x){return -1;} if(this.x > x.x){return 1;} if(this.y < x.y){return -1;} if(this.y > x.y){return 1;} return 0; }
Mar 20 2004
Thanks! I also had to change opEquals to have Object for parametar and it WORKS! ivan "Ben Hinkle" <bhinkle4 juno.com> wrote in message news:2jvo50t4gqi0d2npoqnl98kvksm2ai3sb5 4ax.com...int opCmp(in Point x) { if(this.x < x.x){return -1;} if(this.x > x.x){return 1;} if(this.y < x.y){return -1;} if(this.y >= x.y){return 1;} }opCmp needs to have the same signature as in object.d: int opCmp(Object obj) { Point x = cast(Point)obj; if (x is null) return super.opCmp(xo); if(this.x < x.x){return -1;} if(this.x > x.x){return 1;} if(this.y < x.y){return -1;} if(this.y > x.y){return 1;} return 0; }
Mar 20 2004
Ben Hinkle wrote:That explains something, but I still think Object.opCmp is silly. "The member function opCmp() is defined as part of Object as: int opCmp(Object o); so that every class object has a opCmp()." "For some objects, testing for less or greater makes no sense. For these, override opCmp() with: class A { int opCmp(Object o) { assert(0); // comparison makes no sense return 0; } }" Why should every object have an opCmp? This is one of D's warts I think. Surely if testing for less or greater than makes no sense, then this should be indicated by there being no opCmp method. All this does is turns what ought to be compile-time checks: - whether the class has a natural ordering at all - whether the LHS and RHS are mutually comparable, if they are of different classes into run-time checks. Maybe there's some hidden motive, but I can't see it.... Ivan Senji wrote:opCmp needs to have the same signature as in object.d:Thanks! I also had to change opEquals to have Object for parametar and it WORKS!That makes a bit more sense, if there are occasions when you might want to compare objects of diverse classes for equality. (Maybe some Java programmers have taken advantage of the API containers' ability to arbitrarily mix classes....) But even templates have no difficulty finding a method opEquals(Qwert) in a class Qwert, if faced with an equality expression with two Qwerts. It isn't that difficult to clear associative arrays of this difficulty, is it? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Mar 22 2004
I agree with you that this is a strange bahaviour of D, i realy can't understand why associative arrays us all 3 functions (opEquals, opCmp, toHash)? I could live with it now that i know what needs to be written to make it work, but it would be even nicer if this where documented and explained somewhere! "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:c3n6ou$9en$1 digitaldaemon.com...Ben Hinkle wrote:That explains something, but I still think Object.opCmp is silly. "The member function opCmp() is defined as part of Object as: int opCmp(Object o); so that every class object has a opCmp()." "For some objects, testing for less or greater makes no sense. For these, override opCmp() with: class A { int opCmp(Object o) { assert(0); // comparison makes no sense return 0; } }" Why should every object have an opCmp? This is one of D's warts I think. Surely if testing for less or greater than makes no sense, then this should be indicated by there being no opCmp method. All this does is turns what ought to be compile-time checks: - whether the class has a natural ordering at all - whether the LHS and RHS are mutually comparable, if they are of different classes into run-time checks. Maybe there's some hidden motive, but I can't see it.... Ivan Senji wrote:opCmp needs to have the same signature as in object.d:Thanks! I also had to change opEquals to have Object for parametar and it WORKS!That makes a bit more sense, if there are occasions when you might want to compare objects of diverse classes for equality. (Maybe some Java programmers have taken advantage of the API containers' ability to arbitrarily mix classes....) But even templates have no difficulty finding a method opEquals(Qwert) in a class Qwert, if faced with an equality expression with two Qwerts. It isn't that difficult to clear associative arrays of this difficulty, is it? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Mar 22 2004
Ivan Senji wrote:I agree with you that this is a strange bahaviour of D, i realy can't understand why associative arrays us all 3 functions (opEquals, opCmp, toHash)?- toHash - to decide which hash slot to look in - opCmp - to do a binary search within the hash slot, I guess - opEquals - to finally check that the object it's found that's comparatively equivalent is indeed equal But the opCmp stage obviously isn't going to work if the class has no ordering. Here's another difficulty - with the wart, it's tricky to detect the need to skip the opCmp stage. If the presence of an opCmp meant what it should mean, then it would be straightforward to implement an AA so that opCmp'll be used iff it exists.I could live with it now that i know what needs to be written to make it work, but it would be even nicer if this where documented and explained somewhere!<snip top of upside-down reply> I agree. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Mar 23 2004