www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Array with char-keys

reply Charma <Motoko_Kusanagi web.de> writes:
Hello,
i am very new with D (i do know C++ though) so i have a maybe strange question.
Is there any way i can make an array which has char-type keys? Like in php in
which something like that is possible:
array{
    "textbla" => value,
    "anotherText" => value,
    and so on...
}
Or maybe there is another way so i can values in an array with char-strings?
what i want is to save an unsorted file-list in an array, in a way so that i
don't need to look through the whole array to find the file.

Any Idea's?

Thanks
May 24 2007
next sibling parent BCS <ao pathlink.com> writes:
Reply to Charma,

 Hello,
 i am very new with D (i do know C++ though) so i have a maybe strange
 question. Is there any way i can make an array which has char-type
 keys? Like in php in which something like that is possible:
 array{
 "textbla" => value,
 "anotherText" => value,
 and so on...
 }
 Or maybe there is another way so i can values in an array with
 char-strings?
 
 what i want is to save an unsorted file-list in an array, in a way so
 that i don't need to look through the whole array to find the file.
 
 Any Idea's?
 
 Thanks
 
there are assortative arrays: int[ char[] ] arr; this will allow a string to be used as a key into a mapping (it's a hash under the hood). Is that what you want?
May 24 2007
prev sibling next sibling parent reply Pragma <ericanderton yahoo.removeme.com> writes:
Charma wrote:
 Hello,
 i am very new with D (i do know C++ though) so i have a maybe strange
question. Is there any way i can make an array which has char-type keys? Like
in php in which something like that is possible:
 array{
     "textbla" => value,
     "anotherText" => value,
     and so on...
 }
 Or maybe there is another way so i can values in an array with char-strings?
 what i want is to save an unsorted file-list in an array, in a way so that i
don't need to look through the whole array to find the file.
 
 Any Idea's?
 
 Thanks
What you want is an associative array: char[char[]] myMap; myMap["one"] = "first"; myMap["two"] = "second"; myMap["three"] = "third"; http://www.digitalmars.com/d/arrays.html#associative Traversal is also very easy with this type: foreach(key,value; myMap){ writefln("%s => %s",key,value); } Tests are done with the 'in' operator: if("two" in myMap){ writefln("mymap contains a value for 'two'"); } -- - EricAnderton at yahoo
May 24 2007
next sibling parent Charma <Motoko_Kusanagi web.de> writes:
yes! thank you both very much! i am right away to try it. this is a great
forum... my answers are allways answered quick and good.

I will write again if there are any problem.. thanks again ^^;;
May 24 2007
prev sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Pragma Wrote:
 What you want is an associative array:
 
 char[char[]] myMap;
minor correction: char[] [char[]] myMap; Regan
May 24 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Regan Heath wrote:
 Pragma Wrote:
 What you want is an associative array:

 char[char[]] myMap;
minor correction: char[] [char[]] myMap; Regan
Which is a mistake that's a lot harder to make with a little alias magic. Easier to read the intent as well. alias char[] string; string[string] myMap; --bb
May 24 2007
prev sibling parent pragma <ericanderton yahoo.com> writes:
Regan Heath wrote:
 Pragma Wrote:
 What you want is an associative array:

 char[char[]] myMap;
minor correction: char[] [char[]] myMap; Regan
GAh! Wow, note to self: do not post without coffee.
May 24 2007
prev sibling parent reply Charma <Motoko_Kusanagi web.de> writes:
thanks to all..
i have tested it...
seems to work as long as i am writing into the string, but it somehow looks
like it is always overriding the same entry...

i got my class:
class VFIentry
{
	byte VFSfile;
	uint pos;
	uint size;
	byte flags;
}

and later in some code i do this:

VFIentry[char[]] VFIndex; // this is the array


byte VFSt;
char[] namet;
while(!index.eof())
{
	index.readExact(&VFSt, 1);
	index.readExact(&t, 1);
	namet.length = t;
	index.readExact(namet.ptr, t);
	VFIndex[namet] = new VFIentry; // **
	VFIndex[namet].VFSfile = VFSt;	
	index.readExact(&VFIndex[namet].flags, 1);
	index.readExact(&VFIndex[namet].pos, 4);
	index.readExact(&VFIndex[namet].size, 4);
	writefln("file: ", namet, " in VFS-File: ", VFIndex[namet].VFSfile, " pos: ",
VFIndex[namet].pos, " size: ", VFIndex[namet].size);			
}
up to this point it seems to work correctly... i hope it isn't too hard to
understans... i am reading a file that has informations about in which vfs
(virtual file system) the files are and then the name-length, the name, and
other informations...
i want to read them all into the array VFIndex so that i can later get the
informations with VFIndex["file1.dat"] and VFIndex["file2.dat"] and so on...
i think my mistake is at the **-marked line but i am not sure..
anyone any idea?!?
May 25 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Charma wrote:
 thanks to all..
 i have tested it...
 seems to work as long as i am writing into the string, but it somehow looks
like it is always overriding the same entry...
 
 i got my class:
 class VFIentry
 {
 	byte VFSfile;
 	uint pos;
 	uint size;
 	byte flags;
 }
 
 and later in some code i do this:
 
 VFIentry[char[]] VFIndex; // this is the array
 
 
 byte VFSt;
 char[] namet;
 while(!index.eof())
 {
 	index.readExact(&VFSt, 1);
 	index.readExact(&t, 1);
From here...
 	namet.length = t;
 	index.readExact(namet.ptr, t);
 	VFIndex[namet] = new VFIentry; // **
 	VFIndex[namet].VFSfile = VFSt;
...to here is, I think, your problem. Strings in D are arrays, and arrays are reference types. So what's happening here is that you're reading in the file's name, storing it away... and then *overwriting it* on the next file. What you need to do is copy the buffer if you plan on re-using it, or simply create a new buffer in the first place. Since you're actively using namet in several places, I'd replace: namet.length = t; with: namet = new char[t]; And it should work from there.
 	index.readExact(&VFIndex[namet].flags, 1);
 	index.readExact(&VFIndex[namet].pos, 4);
 	index.readExact(&VFIndex[namet].size, 4);
 	writefln("file: ", namet, " in VFS-File: ", VFIndex[namet].VFSfile, " pos: ",
VFIndex[namet].pos, " size: ", VFIndex[namet].size);			
 }
 up to this point it seems to work correctly... i hope it isn't too hard to
understans... i am reading a file that has informations about in which vfs
(virtual file system) the files are and then the name-length, the name, and
other informations...
 i want to read them all into the array VFIndex so that i can later get the
informations with VFIndex["file1.dat"] and VFIndex["file2.dat"] and so on...
 i think my mistake is at the **-marked line but i am not sure..
 anyone any idea?!?
Out of interest, what language(s) are you coming from? -- Daniel P.S. Full disclosure: changing .length *can* give you a new string, but only if the new length doesn't fit into the previously allocated storage. So files with the same length or shorter won't get new storage. Ones that are larger *might*. -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 25 2007
parent reply Charma <Motoko_Kusanagi web.de> writes:
Daniel Keep Wrote:

 
 
 Charma wrote:
 thanks to all..
 i have tested it...
 seems to work as long as i am writing into the string, but it somehow looks
like it is always overriding the same entry...
 
 i got my class:
 class VFIentry
 {
 	byte VFSfile;
 	uint pos;
 	uint size;
 	byte flags;
 }
 
 and later in some code i do this:
 
 VFIentry[char[]] VFIndex; // this is the array
 
 
 byte VFSt;
 char[] namet;
 while(!index.eof())
 {
 	index.readExact(&VFSt, 1);
 	index.readExact(&t, 1);
From here...
 	namet.length = t;
 	index.readExact(namet.ptr, t);
 	VFIndex[namet] = new VFIentry; // **
 	VFIndex[namet].VFSfile = VFSt;
...to here is, I think, your problem. Strings in D are arrays, and arrays are reference types. So what's happening here is that you're reading in the file's name, storing it away... and then *overwriting it* on the next file. What you need to do is copy the buffer if you plan on re-using it, or simply create a new buffer in the first place. Since you're actively using namet in several places, I'd replace: namet.length = t; with: namet = new char[t]; And it should work from there.
 	index.readExact(&VFIndex[namet].flags, 1);
 	index.readExact(&VFIndex[namet].pos, 4);
 	index.readExact(&VFIndex[namet].size, 4);
 	writefln("file: ", namet, " in VFS-File: ", VFIndex[namet].VFSfile, " pos: ",
VFIndex[namet].pos, " size: ", VFIndex[namet].size);			
 }
 up to this point it seems to work correctly... i hope it isn't too hard to
understans... i am reading a file that has informations about in which vfs
(virtual file system) the files are and then the name-length, the name, and
other informations...
 i want to read them all into the array VFIndex so that i can later get the
informations with VFIndex["file1.dat"] and VFIndex["file2.dat"] and so on...
 i think my mistake is at the **-marked line but i am not sure..
 anyone any idea?!?
Out of interest, what language(s) are you coming from? -- Daniel P.S. Full disclosure: changing .length *can* give you a new string, but only if the new length doesn't fit into the previously allocated storage. So files with the same length or shorter won't get new storage. Ones that are larger *might*. -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
thanks a lot! my problem is solved, but to be honest i am not 100% sure why... maybe you could explain that again?!? (sorry about that... english isn't my native language) What I don't understand is why i still need the old name?! once i have saved it in VFIndex, i can override it, right? it is not needed anymore since it is saved in VFIndex, isn't it? About language.. i think you want to know what i used before: C++, acoutally i still use C++ sometimes... I started using D 3 days ago and only because my friend is using it and we are on a project together...
May 25 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Charma wrote:
 Daniel Keep Wrote:
 
 Charma wrote:
 thanks to all..
 i have tested it...
 seems to work as long as i am writing into the string, but it somehow looks
like it is always overriding the same entry...

 i got my class:
 class VFIentry
 {
 	byte VFSfile;
 	uint pos;
 	uint size;
 	byte flags;
 }

 and later in some code i do this:

 VFIentry[char[]] VFIndex; // this is the array


 byte VFSt;
 char[] namet;
 while(!index.eof())
 {
 	index.readExact(&VFSt, 1);
 	index.readExact(&t, 1);
From here...
 	namet.length = t;
 	index.readExact(namet.ptr, t);
 	VFIndex[namet] = new VFIentry; // **
 	VFIndex[namet].VFSfile = VFSt;
...to here is, I think, your problem. Strings in D are arrays, and arrays are reference types. So what's happening here is that you're reading in the file's name, storing it away... and then *overwriting it* on the next file. What you need to do is copy the buffer if you plan on re-using it, or simply create a new buffer in the first place. Since you're actively using namet in several places, I'd replace: namet.length = t; with: namet = new char[t]; And it should work from there.
[snip]
 
 thanks a lot! my problem is solved, but to be honest i am not 100% sure why... 
 maybe you could explain that again?!? (sorry about that... english isn't my
native language)
A dynamic array (let's say T[]) in D is best thought of as a struct { size_t length; T* ptr; }. When you make a copy of it (which happens when you use it as an AA key, for example) this struct is copied, not the data the "ptr" member points to. What you were doing was changing the data it points to while it was still being used as an AA key...
 What I don't understand is why i still need the old name?!
Because the data is still referenced by the AA key.
 once i have saved it in VFIndex, i can override it, right?
You shouldn't overwrite[1] array data once the array reference is "saved" into an AA key. [1] (You can't override it ;) )
 it is not needed anymore since it is saved in VFIndex, isn't it?
It *is* needed since only the _reference_ is "saved" into the AA.
May 25 2007