www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - use variant as associative array

reply GG <g g.com> writes:
I try to use variant as associative array with dmd2.039, 

Variant[char[]][int] aa;
aa[0]["Month"] = "Jan";
aa[0]["Profit"] = 500;
aa[1]["Month"] = "Feb";
aa[1]["Profit"] = 800;

I got core.exception.RangeError main(28): Range violation
I'm doing something wrong ? Or it's same problem as :
http://digitalmars.com/d/archives/digitalmars/D/Variant_string_associative_array_..._fail_87248.html
Same problem with dmd2.040

Thanks !
GG
Feb 10 2010
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Feb 10, 2010 at 22:28, GG <g g.com> wrote:

 I try to use variant as associative array with dmd2.039,

 I got core.exception.RangeError main(28): Range violation
I had the same problem a few months ago. It's the same with Algebraic, too bad. alias TypeTuple!(int, string, double, char) Universe; alias Algebraic!Universe Var; Var[string] test; test["abc"] = 3; // fails, also with range violation. test["abc"] = Var(3); // the same. even wrapped in an Algebraic/Variant call, you cannot initialize it. test = ["abc":3]; // Error: cannot implicitly convert expression (["abc":1]) of type int[string] to VariantN!(maxSize,int,string,double,char)[string] test = ["abc":Var(3)]; // Error: cannot implicitly convert expression (["abc":opCall(3)]) of type VariantN!(maxSize)[string] to... (note the weird expression, but with a correct type.) In the end, I had to use a two-level hack: Variant[] vars; int[char[]][int] indices; vars ~= "Jan"; indices[0]["Month"] = vars.length-1; or something like this. Sad, but true... Philippe
Feb 11 2010
prev sibling next sibling parent reply GG <g g.com> writes:
I tried your trick but I got "Error: cannot append type string to type
VariantN!(maxSize)[]" 
on :  vars ~= "Jan";

I found this : http://d.puremagic.com/issues/show_bug.cgi?id=3692, the issue
has been REOPEN.

Thanks for helping !
Feb 11 2010
next sibling parent GG <g g.com> writes:
Sorry, but I ckicked on REPLY and it created a new thread after posting!?
Feb 11 2010
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Thu, Feb 11, 2010 at 21:22, GG <g g.com> wrote:

 I tried your trick but I got "Error: cannot append type string to type
 VariantN!(maxSize)[]"
 on :  vars ~= "Jan";

 I found this : http://d.puremagic.com/issues/show_bug.cgi?id=3692, the
 issue has been REOPEN.

 Thanks for helping !
Hmm, it worked for me, but that was almost a year ago. Maybe I wrapped a Variant around? vars ~= Variant("Jan"); (*testing*) Yes, it works: Variant[] vars; int[char[]][int] indices; vars ~= Variant("Jan"); indices[0]["Month"] = vars.length-1; Ugly as sin, though, and cumbersome to use. But I used it to add 'properties' to nodes and edges in a graph class (like, adding weight to edges as double, and names to nodes as strings...) and it worked quite well, with a few functions to hide the trick away. But it's sad you can't use Variant directly as a value. You can use it as a key, sort of: int[Variant] test; test[Variant(3)] = 4; // test[3] = 4 does not work test[Variant("abc")] = 0; writeln(test[Variant("abc")]); // 0 auto k = test.keys; // crash! Assertion failure: 'impl' on line 3886 in file 'mtype.c'
Feb 11 2010
prev sibling next sibling parent downs <default_357-line yahoo.de> writes:
On 10.02.2010 22:28, GG wrote:
 I try to use variant as associative array with dmd2.039, 
 
 Variant[char[]][int] aa;
 aa[0]["Month"] = "Jan";
 aa[0]["Profit"] = 500;
 aa[1]["Month"] = "Feb";
 aa[1]["Profit"] = 800;
 
 I got core.exception.RangeError main(28): Range violation
 I'm doing something wrong ? Or it's same problem as :
 http://digitalmars.com/d/archives/digitalmars/D/Variant_string_associative_array_..._fail_87248.html
 Same problem with dmd2.040
 
 Thanks !
 GG
I don't have a D2 compiler, but try this. Variant[char[]] v; aa[0] = v; aa[0]["Month"] = "Jan"; If that also fails, file a bug.
Feb 11 2010
prev sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
GG wrote:
 I try to use variant as associative array with dmd2.039, 
 
 Variant[char[]][int] aa;
 aa[0]["Month"] = "Jan";
 aa[0]["Profit"] = 500;
 aa[1]["Month"] = "Feb";
 aa[1]["Profit"] = 800;
 
 I got core.exception.RangeError main(28): Range violation
 I'm doing something wrong ? Or it's same problem as :
 http://digitalmars.com/d/archives/digitalmars/D/Variant_string_associative_array_..._fail_87248.html
 Same problem with dmd2.040
 
 Thanks !
 GG
I got the following to work with Tango's Variant (dmd 1.051 + pre-0.99.9 trunk): Variant[char[]][int] aa; aa[0] = typeof(aa[0]).init; aa[0]["Month"] = Variant("Jan"); aa[0]["Profit"] = Variant(500); aa[1] = typeof(aa[0]).init; aa[1]["Month"] = Variant("Feb"); aa[1]["Profit"] = Variant(800); There's actually two problems at work here: 1. You can't use a nested associative array without initialising it. 2. You apparently can't assign to an aa of Variants for some reason. Keep in mind that Variants are basically a hack on the language; that assigning to a Variant value in an AA doesn't work isn't entirely surprising.
Feb 11 2010
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Daniel Keep wrote:
 I got the following to work with Tango's Variant (dmd 1.051 + pre-0.99.9
 trunk):
 
     Variant[char[]][int] aa;
 
     aa[0] = typeof(aa[0]).init;
     aa[0]["Month"] = Variant("Jan");
     aa[0]["Profit"] = Variant(500);
 
     aa[1] = typeof(aa[0]).init;
     aa[1]["Month"] = Variant("Feb");
     aa[1]["Profit"] = Variant(800);
 
 There's actually two problems at work here:
 
 1. You can't use a nested associative array without initialising it.
Scratch that; it does work. Huh. Fancy that.
 2. You apparently can't assign to an aa of Variants for some reason.
 
 Keep in mind that Variants are basically a hack on the language; that
 assigning to a Variant value in an AA doesn't work isn't entirely
 surprising.
Another thing that occurred to me; is there any reason you can't do this:
 struct Record
 {
     char[] month;
     int profit;
 }

 Record[int] aa;

 aa[0] = Record("Jan", 500);
 aa[1] = Record("Feb", 800);
Or even this:
 Record[] arr;
 arr ~= Record("Jan", 500);
 arr ~= Record("Feb", 800);
Or even even this:
 enum Month { Jan, Feb, Mar, /* and the rest */ }
 struct Record { Month month; int profit }
 Record[] arr;
 arr ~= Record(Month.Jan, 500);
 arr ~= Record(Month.Feb, 800);
?
Feb 11 2010
parent reply GG <g g.com> writes:
Yes I can't use struct and/or enum because I can't know type and number of data
that user could pass.
In this example, we talk about Month, but it could be Minutes, week... So I try
to program dynamic not static.

In fact I'm learning D thought a little project of graphic chart. I would like
to keep a notion that I have found very usefull in AS3 : ArrayCollection.

I just want to know if it possible in D to have only one BIG collection of any
type of data (int,string,bool,double...) ?

We talk about Variant but it could be other ? Maybe not...

So I tried this :
        Variant[char[]][int] aa;

	aa[0]["Month"] = Variant("Jan"); // compile
	aa[0]["Profit"] = Variant(500); // compile

	aa[1]["Month"] = Variant("Feb");  // compile
	aa[1]["Profit"] = Variant(800); // compile
	
	for(int i=0;i<aa.length;i++) // compile failed on aa.length and get dmd:
mtype.c:3426: StructDeclaration* TypeAArray::getImpl(): Assertion `impl' failed.
	{
		writefln("%s",aa[i]["Month"]); // compile but get at runtime :
core.exception.RangeError test(25): Range violation
	}
It seems to be a bug...

Thanks  !
Feb 11 2010
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
GG wrote:
 Yes I can't use struct and/or enum because I can't know type and number of
data that user could pass.
 In this example, we talk about Month, but it could be Minutes, week... So I
try to program dynamic not static.
If you're trying to program dynamically, then you're using the wrong language. Writing dynamically-typed code in D is like trying to write C in Python; it's missing the language's strengths.
 In fact I'm learning D thought a little project of graphic chart. I would like
to keep a notion that I have found very usefull in AS3 : ArrayCollection.
AS3 is dynamically typed; D is not. Variant can be used to 'fake' dynamic typing, but only to a certain degree. You can't call methods on Variants, operations on them are kinda flaky, etc.
 I just want to know if it possible in D to have only one BIG collection of any
type of data (int,string,bool,double...) ?
Arrays of Variant.
 We talk about Variant but it could be other ? Maybe not...
 
 So I tried this :
         Variant[char[]][int] aa;
 
 	aa[0]["Month"] = Variant("Jan"); // compile
 	aa[0]["Profit"] = Variant(500); // compile
 
 	aa[1]["Month"] = Variant("Feb");  // compile
 	aa[1]["Profit"] = Variant(800); // compile
 	
 	for(int i=0;i<aa.length;i++) // compile failed on aa.length and get dmd:
mtype.c:3426: StructDeclaration* TypeAArray::getImpl(): Assertion `impl' failed.
AAs don't have a length (as far as I remember). Besides which, there's NOTHING that says the keys for aa are sequential. If you want a sequence, use an array. You should probably read the documentation on how to use AAs.
 	{
 		writefln("%s",aa[i]["Month"]); // compile but get at runtime :
core.exception.RangeError test(25): Range violation
 	}
What you want is probably more along these lines: foreach( k,v ; aa ) { writefln("%s", v); }
 It seems to be a bug...
 
 Thanks  !
Feb 11 2010
prev sibling parent reply GG <g g.com> writes:
I tried std.boxer,
        Box[char[]][int] bb;
	bb[0]["Month"] = box("Jan");
	bb[0]["Profit"] = box(800);
	bb[1]["Month"] = box("Jan");
	bb[1]["Profit"] = box(200);
	
        /*section work*/
	writefln("%s",bb[0]["Month"]);
	writefln("%d",bb[0]["Profit"]);
	writefln("%s",bb[1]["Month"]);
	writefln("%d",bb[1]["Profit"]);
        /*end section*/

	for(int i=0;i<bb.length;i++) // can't do .length with box, so can't pass on
array :-(
	{
		writefln("%s",bb[i]["Month"]);
		writefln("%d",bb[i]["Profit"]);
	}

But I found this : http://www.digitalmars.com/d/archives/D/gnu/Issue_1968_New_boxer.d_does_not_work_3168.html

They say to use std.variant for new code...
So with std.boxer, we can save and get data by indice directly but no property
.length

With std.variant, we can save data but can't access to data (ex:
aa[i]["Month"]) // Range violation

Thanks !
Feb 11 2010
parent GG <g g.com> writes:
We can't assign value to Variant associative array because there is a bug, I
found this :
http://d.puremagic.com/issues/show_bug.cgi?id=2451
So the issue is already assigned...I'm waiting.

Yes there is a .length for associative array and now aa.length works with the
last fix :
http://d.puremagic.com/issues/show_bug.cgi?id=3692

Thanks !
GG
Feb 13 2010