Thread overview
use variant as associative array
Feb 10, 2010
GG
Feb 11, 2010
Philippe Sigaud
Feb 11, 2010
downs
Feb 12, 2010
Daniel Keep
Feb 12, 2010
Daniel Keep
Feb 12, 2010
GG
Feb 12, 2010
Daniel Keep
Feb 12, 2010
GG
Feb 14, 2010
GG
February 10, 2010
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
February 11, 2010
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


February 11, 2010
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.
February 12, 2010
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.
February 12, 2010

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);

?
February 12, 2010
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  !
February 12, 2010

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  !
February 12, 2010
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 !
February 14, 2010
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