digitalmars.D.learn - Two-dimensional associateive arrays?
- Tyler (5/5) Feb 02 2006 I'm working on converting a program from C to D and one of the data stru...
- Chris Sauls (13/20) Feb 02 2006 Its a simple, and common mistake for thsoe new to D arrays. The basic t...
- Ivan Senji (3/28) Feb 02 2006 Common mistake indeed, but the above doesn't work. Instead you get
- Chris Sauls (7/38) Feb 02 2006 I had to think about it for a bit, but I know why... and it dregs up an ...
- Ivan Senji (7/16) Feb 02 2006 As you said assignment normally creates the key, so i would vote for bug...
- Chris Sauls (11/33) Feb 02 2006 # template makeStaticArray!(T_Type, size_t T_Size) {
- Ivan Senji (5/30) Feb 02 2006 But with the folowing problems:
- Bruno Medeiros (18/32) Feb 09 2006 Not a bug. Assignment only creates a key in the form:
- Ivan Senji (7/31) Feb 09 2006 I realized that. So there is now solution to the problem of associative
- Bruno Medeiros (16/41) Feb 10 2006 It won't work because you cannot assign to static arrays, not because it...
- Russ Lewis (6/37) Feb 06 2006 The integer array (i.e. the init value of example["foo"]) inits to
- Ivan Senji (16/24) Feb 07 2006 You can't set length of a static array, you get (as expected):
- Russ Lewis (2/14) Feb 07 2006 Sorry, can't believe I overlooked that.
- Derek Parnell (33/40) Feb 07 2006 On Tue, 07 Feb 2006 14:56:11 +0100, Ivan Senji wrote:
- Ivan Senji (11/56) Feb 07 2006 Thanks for the answer. Yes i do these sort of things but that is not the...
- Regan Heath (36/46) Feb 02 2006 I believe that sort of array should be declared:
- BCS (3/9) Feb 02 2006 quoted code, not quotes in code.
- Regan Heath (3/10) Feb 02 2006 Oops, my apologies.
- Tyler (17/17) Feb 02 2006 Thanks for all your help! I decided that it would just be easier to use...
- Regan Heath (4/27) Feb 02 2006 Typo "fooLengths" != "fooLenghts" the h and t are switched.
- Tyler (2/2) Feb 03 2006 D'oh! Thanks for pointing out that typo. After staring at that code fo...
- Tyler (16/16) Feb 03 2006 Alright, now I have another question. I finally got the program to comp...
- James Dunne (2/25) Feb 03 2006 I'd have to see more code...
- Unknown W. Brackets (41/64) Feb 04 2006 Looks to me like example.inner is a dynamic array. You'll probably have...
- Deewiant (9/37) Feb 04 2006 This also works, but I'm not so sure it's supposed to:
- Jarrett Billingsley (6/14) Feb 04 2006 Yeah, all you're doing is copying the values of the new X (i.e. the defa...
- Unknown W. Brackets (2/24) Feb 04 2006
- Tyler (1/1) Feb 05 2006 Thanks again everyone.
I'm working on converting a program from C to D and one of the data structures in it could be more easily represented in D as an associative array of arrays of 2 integers (i.e. "int[char[]][2] example;") Can D do this? The latgest DMD compiler lets me declare it, but when I try to use it ("example["foo"][1] = 55;") it gives me errors about how it can't implicitly cast char[] to int.
Feb 02 2006
Tyler wrote:I'm working on converting a program from C to D and one of the data structures in it could be more easily represented in D as an associative array of arrays of 2 integers (i.e. "int[char[]][2] example;") Can D do this? The latgest DMD compiler lets me declare it, but when I try to use it ("example["foo"][1] = 55;") it gives me errors about how it can't implicitly cast char[] to int.Its a simple, and common mistake for thsoe new to D arrays. The basic thing to remember, is that decleration and usage are in reverse syntactic directions, and declerations are "read" from right to left. In other words: In the case above, the decleration "reads" as "an association of char[]'s to static arrays, length 2, of int's." Your original decleration "reads" as "a static array, length 2, of associations of char[]'s to int's." -- Chris Sauls
Feb 02 2006
Chris Sauls wrote:Tyler wrote:Common mistake indeed, but the above doesn't work. Instead you get ArrayBoundsError. Why would that be?I'm working on converting a program from C to D and one of the data structures in it could be more easily represented in D as an associative array of arrays of 2 integers (i.e. "int[char[]][2] example;") Can D do this? The latgest DMD compiler lets me declare it, but when I try to use it ("example["foo"][1] = 55;") it gives me errors about how it can't implicitly cast char[] to int.Its a simple, and common mistake for thsoe new to D arrays. The basic thing to remember, is that decleration and usage are in reverse syntactic directions, and declerations are "read" from right to left. In other words:
Feb 02 2006
Ivan Senji wrote:Chris Sauls wrote:I had to think about it for a bit, but I know why... and it dregs up an ancient topic. It issues the ArrayBoundsError because the key "foo" does not yet exist. Now, normally an assignment expression creates the key, but apparently when one includes extra dimensions then D doesn't catch this. Bug? Or annoying feature? -- Chris SaulsTyler wrote:Common mistake indeed, but the above doesn't work. Instead you get ArrayBoundsError. Why would that be?I'm working on converting a program from C to D and one of the data structures in it could be more easily represented in D as an associative array of arrays of 2 integers (i.e. "int[char[]][2] example;") Can D do this? The latgest DMD compiler lets me declare it, but when I try to use it ("example["foo"][1] = 55;") it gives me errors about how it can't implicitly cast char[] to int.Its a simple, and common mistake for thsoe new to D arrays. The basic thing to remember, is that decleration and usage are in reverse syntactic directions, and declerations are "read" from right to left. In other words:
Feb 02 2006
Chris Sauls wrote:I had to think about it for a bit, but I know why... and it dregs up an ancient topic. It issues the ArrayBoundsError because the key "foo" does not yet exist. Now, normally an assignment expression creates the key, but apparently when one includes extra dimensions then D doesn't catch this. Bug? Or annoying feature?As you said assignment normally creates the key, so i would vote for bug. But the bigger problem is how would one manully create a static array. It just isn't possible. If examples was int[][char[]] example, you could do something like example["foo"] = makeArray!(int)(55,56); but in this case is there anything that can be done?-- Chris Sauls
Feb 02 2006
Ivan Senji wrote:Chris Sauls wrote:%d"), data.length, T_Size)); Maybe? -- Chris SaulsI had to think about it for a bit, but I know why... and it dregs up an ancient topic. It issues the ArrayBoundsError because the key "foo" does not yet exist. Now, normally an assignment expression creates the key, but apparently when one includes extra dimensions then D doesn't catch this. Bug? Or annoying feature?As you said assignment normally creates the key, so i would vote for bug. But the bigger problem is how would one manully create a static array. It just isn't possible. If examples was int[][char[]] example, you could do something like example["foo"] = makeArray!(int)(55,56); but in this case is there anything that can be done?-- Chris Sauls
Feb 02 2006
Chris Sauls wrote:Ivan Senji wrote:Nice template..As you said assignment normally creates the key, so i would vote for bug. But the bigger problem is how would one manully create a static array. It just isn't possible. If examples was int[][char[]] example, you could do something like example["foo"] = makeArray!(int)(55,56); but in this case is there anything that can be done?expected %d"), data.length, T_Size));-- Chris SaulsMaybe?But with the folowing problems: - functions can not return static arrays - you can not assign to static array
Feb 02 2006
Ivan Senji wrote:Chris Sauls wrote:Not a bug. Assignment only creates a key in the form: example["foo"] = ... and not: example["foo"][2] = ... Because the latter is index assignment of the static array, not of the associative array.I had to think about it for a bit, but I know why... and it dregs up an ancient topic. It issues the ArrayBoundsError because the key "foo" does not yet exist. Now, normally an assignment expression creates the key, but apparently when one includes extra dimensions then D doesn't catch this. Bug? Or annoying feature?As you said assignment normally creates the key, so i would vote for bug.But the bigger problem is how would one manully create a static array. It just isn't possible.You could simply try to assign to another static array, but the problem is that you cannot assign to static arrays, so this will never work: example["foo"] = ... -> What could probably be made, is to not allow creation of types of the following structure: int[2][] example; That is, one can't create dynamic arrays with static elements. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 09 2006
Bruno Medeiros wrote:Ivan Senji wrote:I realized that. So there is now solution to the problem of associative array of static arrays.As you said assignment normally creates the key, so i would vote for bug.Not a bug. Assignment only creates a key in the form: example["foo"] = ... and not: example["foo"][2] = ... Because the latter is index assignment of the static array, not of the associative array.That is exactly what my "just isn't possible" meant.But the bigger problem is how would one manully create a static array. It just isn't possible.You could simply try to assign to another static array, but the problem is that you cannot assign to static arrays, so this will never work: example["foo"] = ...-> What could probably be made, is to not allow creation of types of the following structure: int[2][] example;NOOO! Are you trying to break my existing code? :) This works and i use this! There is no reason why this wouldn't work.That is, one can't create dynamic arrays with static elements.Yes, one can, but can't create associative arrays of static arrays.
Feb 09 2006
Ivan Senji wrote:Bruno Medeiros wrote:It won't work because you cannot assign to static arrays, not because it isn't possible to create a static arrays [literal]. (They're different things)Ivan Senji wrote:That is exactly what my "just isn't possible" meant.But the bigger problem is how would one manully create a static array. It just isn't possible.You could simply try to assign to another static array, but the problem is that you cannot assign to static arrays, so this will never work: example["foo"] = ...Damn, you are correct. It is true my initial assumption that you also can not do this (assign to a static array) with dynamic arrays: example[10] = ... ; //(assign to a static array) So I was thinking that dynamic arrays with static elements wouldn't work too. However, I forgot that in the case of dynamic arrays, one can create elements by changing length. Thus the following is possible: example.length = 10 example[0][] = ... ; //(copy to a static array, that is ok) -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."-> What could probably be made, is to not allow creation of types of the following structure: int[2][] example;NOOO! Are you trying to break my existing code? :) This works and i use this! There is no reason why this wouldn't work.That is, one can't create dynamic arrays with static elements.Yes, one can, but can't create associative arrays of static arrays.
Feb 10 2006
Ivan Senji wrote:Chris Sauls wrote:The integer array (i.e. the init value of example["foo"]) inits to length 0. Try this: int[2][char[]] example; example["foo"].length = 2; example["foo"][1] = 55;Tyler wrote:Common mistake indeed, but the above doesn't work. Instead you get ArrayBoundsError. Why would that be?I'm working on converting a program from C to D and one of the data structures in it could be more easily represented in D as an associative array of arrays of 2 integers (i.e. "int[char[]][2] example;") Can D do this? The latgest DMD compiler lets me declare it, but when I try to use it ("example["foo"][1] = 55;") it gives me errors about how it can't implicitly cast char[] to int.Its a simple, and common mistake for thsoe new to D arrays. The basic thing to remember, is that decleration and usage are in reverse syntactic directions, and declerations are "read" from right to left. In other words:
Feb 06 2006
Russ Lewis wrote:The integer array (i.e. the init value of example["foo"]) inits to length 0. Try this: int[2][char[]] example; example["foo"].length = 2;You can't set length of a static array, you get (as expected): constant example["foo"].length is not an lvalue Am I the only one that is (again) begining to think that although D does some thing with arrays great for example slicing and ~, that there are very very big flaws? What I thing D is missing are two types of dynamic arrays: 1. The one we have now: int[][] bla = new int[2]; bla[0].length = 5; bla[1].length = 100; 2. Dynamic rectangular arrays: Static arrays can be useful sometimes but many many times i don't know the exact size at compile-time but still want a tightly packed multidimensional rectangular array.example["foo"][1] = 55;
Feb 07 2006
Ivan Senji wrote:Russ Lewis wrote:Sorry, can't believe I overlooked that.The integer array (i.e. the init value of example["foo"]) inits to length 0. Try this: int[2][char[]] example; example["foo"].length = 2;You can't set length of a static array, you get (as expected):
Feb 07 2006
On Tue, 07 Feb 2006 14:56:11 +0100, Ivan Senji wrote: [snip]2. Dynamic rectangular arrays: Static arrays can be useful sometimes but many many times i don't know the exact size at compile-time but still want a tightly packed multidimensional rectangular array.In the meantime, you can do this sort of thing ... template InitRectArray(T) { T[][] InitRectArray(int i, int j) { T[][] lTemp; lTemp.length = i; lTemp[] = new T[j]; return lTemp; } } import std.stdio; void main() { int[][] bla; bla = InitRectArray!(int)(7,3); foreach( int i, int[] a; bla ) { foreach(int j, int b; a) { writefln(i, "," , j); } } } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 8/02/2006 11:50:53 AM
Feb 07 2006
Derek Parnell wrote:On Tue, 07 Feb 2006 14:56:11 +0100, Ivan Senji wrote: [snip]Thanks for the answer. Yes i do these sort of things but that is not the point. The point is: arrays are the most basic concept of a language. Far more basic than even classes and delegates, and doing it right in the language is important. It is funny how you can do all these wonderfull thing with arrays like dynamically resize and slice them, have associative arrays... but also not to be able to use array literals or dynamic rectangular arrays.2. Dynamic rectangular arrays: Static arrays can be useful sometimes but many many times i don't know the exact size at compile-time but still want a tightly packed multidimensional rectangular array.In the meantime, you can do this sort of thing ...template InitRectArray(T) { T[][] InitRectArray(int i, int j) { T[][] lTemp; lTemp.length = i; lTemp[] = new T[j]; return lTemp; } } import std.stdio; void main() { int[][] bla; bla = InitRectArray!(int)(7,3); foreach( int i, int[] a; bla ) { foreach(int j, int b; a) { writefln(i, "," , j); } } }Although this template does allow to emulate the creation of a rectangular-looking array it in fact isn't. Rectangular array must be continuous in memory, not a bunch of references to 1D arrays.
Feb 07 2006
On Thu, 2 Feb 2006 20:23:00 +0000 (UTC), Tyler <Tyler_member pathlink.com> wrote:I'm working on converting a program from C to D and one of the data structures in it could be more easily represented in D as an associative array of arrays of 2 integers (i.e. "int[char[]][2] example;") Can D do this? The latgest DMD compiler lets me declare it, but when I try to use it ("example["foo"][1] = 55;") it gives me errors about how it can't implicitly cast char[] to int.I believe that sort of array should be declared: int[2][char[]] example; Further "55;" is a string literal, in this case a char[], not a fixed array of 2 integers. However, part of the problem you are going to have is the inability to define a fixed array of 2 integers without making it "static". void foo(int[2] a) {} void main() { int[2] a = [1,2]; //fails static int[2] b = [1,2]; //works foo(b); //works foo([2,3]); //fails } Further, you can't create a dynamic array of integers either, eg. void bar(int[] a) {} void main() { bar([2,3]); //fails } I believe the intention is to support this at a later stage. However, right now there are a number of templates which can achieve this. I don't have one but someone else is likely to post one for you. So, I suspect the way you're going to have to solve this is.. int[][char[]] example; example["label"] = makeArray!(int)(1,2); or similar, where makeArray is the template I mentioned. Alternately if your values come in string form a function like.. int[] parseIntPair(char[] data) { } which converts from the string into a dynamic array of integers could be used. Regan
Feb 02 2006
Regan Heath wrote:On Thu, 2 Feb 2006 20:23:00 +0000 (UTC), Tyler <Tyler_member pathlink.com> wrote:with a little reformatting...quoted code, not quotes in code.[...] ("example["foo"][1] = 55;") [...]Further "55;" is a string literal, in this case a char[], not a fixed
Feb 02 2006
On Thu, 02 Feb 2006 12:52:32 -0800, BCS <BCS_member pathlink.com> wrote:Regan Heath wrote:Oops, my apologies. ReganOn Thu, 2 Feb 2006 20:23:00 +0000 (UTC), Tyler <Tyler_member pathlink.com> wrote:with a little reformatting... >> [...] ("example["foo"][1] = 55;") [...] quoted code, not quotes in code.Further "55;" is a string literal, in this case a char[], not a fixed
Feb 02 2006
Thanks for all your help! I decided that it would just be easier to use a struct like I did in the C version. Now I have another question though. I have a structure (not related to the first question) containing a 2 dynamic arrays of ints, like this: struct EXAMPLE_STRUCT { int[] fooLenghts; int[] barLenghts; } When I try to use either fooLenghts or barLenghts (see below for an example) DMD tells me that there is no property 'fooLenghts' for type 'EXAMPLE_STRUCT'. What am I doing wrong? void someFunc(inout EXAMPLE_STRUCT example) { example.fooLengths.length = length + 1; //DMD: no property 'fooLenghts' for type 'EXAMPLE_STRUCT' example.fooLenghts[length-1] = 55; //(same message) }
Feb 02 2006
On Fri, 3 Feb 2006 04:37:04 +0000 (UTC), Tyler <Tyler_member pathlink.com> wrote:Thanks for all your help! I decided that it would just be easier to use a struct like I did in the C version. Now I have another question though. I have a structure (not related to the first question) containing a 2 dynamic arrays of ints, like this: struct EXAMPLE_STRUCT { int[] fooLenghts; int[] barLenghts; } When I try to use either fooLenghts or barLenghts (see below for an example) DMD tells me that there is no property 'fooLenghts' for type 'EXAMPLE_STRUCT'. What am I doing wrong? void someFunc(inout EXAMPLE_STRUCT example) { example.fooLengths.length = length + 1; //DMD: no property 'fooLenghts' for type 'EXAMPLE_STRUCT' example.fooLenghts[length-1] = 55; //(same message) }Typo "fooLengths" != "fooLenghts" the h and t are switched. Regan
Feb 02 2006
D'oh! Thanks for pointing out that typo. After staring at that code for a good while I have no clue how I missed it (and now it works!)
Feb 03 2006
Alright, now I have another question. I finally got the program to compile, but when I run it I get an array out of bounds error while trying to do the following: struct INNER_STRUCT { int foo; int bar; } struct EAMPLE_STRUCT { OTHER_STRUCT[] unimportant; //(should be) unrelated to problem INNER_STRUCT[char[]] inner; } //global variable EXAMPLE_STRUCT example; /* ...SNIP... */ example.inner[exampString].foo = 15; //Generates ArrayBoundsError (exampString is a char[] of non-zero length)
Feb 03 2006
Tyler wrote:Alright, now I have another question. I finally got the program to compile, but when I run it I get an array out of bounds error while trying to do the following: struct INNER_STRUCT { int foo; int bar; } struct EAMPLE_STRUCT { OTHER_STRUCT[] unimportant; //(should be) unrelated to problem INNER_STRUCT[char[]] inner; } //global variable EXAMPLE_STRUCT example; /* ...SNIP... */ example.inner[exampString].foo = 15; //Generates ArrayBoundsError (exampString is a char[] of non-zero length)I'd have to see more code...
Feb 03 2006
Looks to me like example.inner is a dynamic array. You'll probably have to do: INNER_STRUCT temp_inner; temp_inner.foo = 15; example.inner[exampString] = temp_inner; D used to create keys on read and write, but now it does so only on write. In your example, you're reading from the associative array, and then writing to the result of that. For an example using code, consider this struct: struct X { int y; } This code fails with an ArrayBoundsError: int main() { X[char[]] x; x["test"].y= 1; return 0; } This code works: int main() { X[char[]] x; X temp_x; temp_x.y = 1; x["test"] = temp_x; return 0; } You could also do this: int main() { X[char[]] x; X temp_x; x["test"] = temp_x; x["test"].y = 1; return 0; } Or use a more complicated template. Hope that helps, -[Unknown]Alright, now I have another question. I finally got the program to compile, but when I run it I get an array out of bounds error while trying to do the following: struct INNER_STRUCT { int foo; int bar; } struct EAMPLE_STRUCT { OTHER_STRUCT[] unimportant; //(should be) unrelated to problem INNER_STRUCT[char[]] inner; } //global variable EXAMPLE_STRUCT example; /* ...SNIP... */ example.inner[exampString].foo = 15; //Generates ArrayBoundsError (exampString is a char[] of non-zero length)
Feb 04 2006
Unknown W. Brackets wrote:This code works: int main() { X[char[]] x; X temp_x; temp_x.y = 1; x["test"] = temp_x; return 0; } You could also do this: int main() { X[char[]] x; X temp_x; x["test"] = temp_x; x["test"].y = 1; return 0; } Or use a more complicated template.This also works, but I'm not so sure it's supposed to: struct X { int y; } void main() { X[char[]] x; x["test"] = *new X; x["test"].y = 1; } Is it allowed to use new like that?
Feb 04 2006
"Deewiant" <deewiant.doesnotlike.spam gmail.com> wrote in message news:ds2q7t$2cgg$1 digitaldaemon.com...This also works, but I'm not so sure it's supposed to: struct X { int y; } void main() { X[char[]] x; x["test"] = *new X; x["test"].y = 1; } Is it allowed to use new like that?Yeah, all you're doing is copying the values of the new X (i.e. the default values for an X) into the slot. You can also skip the new and just use x["test"] = X.init; That works as well.
Feb 04 2006
Ah, that looks nicer. I should have done/thought of that. -[Unknown]"Deewiant" <deewiant.doesnotlike.spam gmail.com> wrote in message news:ds2q7t$2cgg$1 digitaldaemon.com...This also works, but I'm not so sure it's supposed to: struct X { int y; } void main() { X[char[]] x; x["test"] = *new X; x["test"].y = 1; } Is it allowed to use new like that?Yeah, all you're doing is copying the values of the new X (i.e. the default values for an X) into the slot. You can also skip the new and just use x["test"] = X.init; That works as well.
Feb 04 2006