www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - dynamic get from variantArray() data table

reply data pulverizer <data.pulverizer gmail.com> writes:
Hi,

I am trying to use variantArray() as a data table object to hold 
columns each of which is an array of a specific type. I need to 
be able to get values from data table but I am having problems ...


import std.stdio; // i/o
import std.variant; // type variations

void main(){
   // Columns of the table
   string[] names = ["walter", "paul", "jeff", "andrie"];
   int[] age = [55, 62, 27, 52];
   string[] language = ["D", "Haskell", "Julia", "D"];
   Variant[] dt = variantArray(names, age, language);

   foreach(col; dt){
     foreach(el; col){
       // here I try a kind of dynamic cast operator
       auto x = el.get!(type(el)); // gives error
       write(x);
     }
     write("\n");
   }
}

data_table.d(37): Error: cannot infer type for el
data_table.d(38): Error: undefined identifier 'el'

Help

DP
Oct 13 2015
parent reply Alex Parrill <initrd.gz gmail.com> writes:
On Tuesday, 13 October 2015 at 15:17:15 UTC, data pulverizer 
wrote:
 Hi,

 I am trying to use variantArray() as a data table object to 
 hold columns each of which is an array of a specific type. I 
 need to be able to get values from data table but I am having 
 problems ...


 import std.stdio; // i/o
 import std.variant; // type variations

 void main(){
   // Columns of the table
   string[] names = ["walter", "paul", "jeff", "andrie"];
   int[] age = [55, 62, 27, 52];
   string[] language = ["D", "Haskell", "Julia", "D"];
   Variant[] dt = variantArray(names, age, language);

   foreach(col; dt){
     foreach(el; col){
       // here I try a kind of dynamic cast operator
       auto x = el.get!(type(el)); // gives error
       write(x);
     }
     write("\n");
   }
 }

 data_table.d(37): Error: cannot infer type for el
 data_table.d(38): Error: undefined identifier 'el'

 Help

 DP
You're trying to iterate over a `Variant`, which isn't implemented. You don't want to use a variant here anyway; you should use a struct or tuple for each entry in the table. import std.typecons; alias Entry = Tuple!(string, int, string); void main() { auto table = [Entry("walter", 55, "D"), Entry("paul", 62, "Haskell"), ... ]; // complete array foreach(entry; table) { writeln(entry.expand); } }
Oct 13 2015
parent reply data pulverizer <data.pulverizer gmail.com> writes:
Thanks for the suggestion Alex, however I need the dynamic 
behaviour properties of variantArray(), writing a struct each 
time would be undesirable.

Perhaps I could boil down the question to something like, is 
there a way of writing

auto x = dt[0][0];
auto y = x.get!(x.type - or whatever); // to get the actual value 
of x rather than .VariantN! ... type

For some kind of auto cast back to basic type.

On Tuesday, 13 October 2015 at 15:51:40 UTC, Alex Parrill wrote:
 On Tuesday, 13 October 2015 at 15:17:15 UTC, data pulverizer 
 wrote:
 Hi,

 I am trying to use variantArray() as a data table object to 
 hold columns each of which is an array of a specific type. I 
 need to be able to get values from data table but I am having 
 problems ...


 import std.stdio; // i/o
 import std.variant; // type variations

 void main(){
   // Columns of the table
   string[] names = ["walter", "paul", "jeff", "andrie"];
   int[] age = [55, 62, 27, 52];
   string[] language = ["D", "Haskell", "Julia", "D"];
   Variant[] dt = variantArray(names, age, language);

   foreach(col; dt){
     foreach(el; col){
       // here I try a kind of dynamic cast operator
       auto x = el.get!(type(el)); // gives error
       write(x);
     }
     write("\n");
   }
 }

 data_table.d(37): Error: cannot infer type for el
 data_table.d(38): Error: undefined identifier 'el'

 Help

 DP
You're trying to iterate over a `Variant`, which isn't implemented. You don't want to use a variant here anyway; you should use a struct or tuple for each entry in the table. import std.typecons; alias Entry = Tuple!(string, int, string); void main() { auto table = [Entry("walter", 55, "D"), Entry("paul", 62, "Haskell"), ... ]; // complete array foreach(entry; table) { writeln(entry.expand); } }
Oct 13 2015
parent Alex Parrill <initrd.gz gmail.com> writes:
On Tuesday, 13 October 2015 at 16:22:36 UTC, data pulverizer 
wrote:
 Thanks for the suggestion Alex, however I need the dynamic 
 behaviour properties of variantArray(), writing a struct each 
 time would be undesirable.

 Perhaps I could boil down the question to something like, is 
 there a way of writing

 auto x = dt[0][0];
 auto y = x.get!(x.type - or whatever); // to get the actual 
 value of x rather than .VariantN! ... type

 For some kind of auto cast back to basic type.
The problem is that you can't do `x.get!(x.type)`, because the type of the expression must be known at compile time, but `x.type` is a runtime value. You'd have to create a branch for each type that `x.type` might be. But again, unless you are dealing with a truly dynamic layout (and not a bunch of fixed layouts), there's better options. For example, you can use `std.range.zip` to iterate through each column array in lockstep, returning tuples for each element. foreach(entry; zip(names, ages, languages)) { write(entry.expand); }
Oct 13 2015