Printing Tuple!(...)[] using for loop?
Steven Schveighoffer
schveiguy at gmail.com
Fri Jul 2 14:09:59 UTC 2021
On 7/2/21 12:21 AM, Kirill wrote:
> I have a `Tuple!(string, ..., string)[] data` that I would like to print
> out:
> `a b c`
> `1 2 3`
> `4 5 6`
>
> Furthermore, I want to be able to print any N rows and M columns of
> that table. For instance:
> `b c`
> `2 3`
> or
> `1 2 3`
> `4 5 6`
>
> I am using for loops for that:
>
> // inside some function(rows, cols):
> immutable startFromRow = ...;
> immutable endWithRow = ...;
> immutable startFromCol = ...;
> immutable endWithCol = ...;
>
> // print data
> for(size_t i = startFromRow; i < endWithRow; i++) {
> for(size_t j = startFromCol; j < endWithCol; j++) {
> writef("%s", data[i][j]);
> }
> writef("\n");
> }
>
> And the compiler puts out the following:
> `Error: variable 'j' cannot be read at compile time`
>
> I tried `data[i].expand[j]`, but the same error occurs anyway.
>
> I have two questions:
> 1. How do I print the contents of a Tuple using for loops? Or any other
> method?
> 2. What am I missing? How does it actually work under the hood?
So a tuple is really like an unnamed group of variables.
A `Tuple!(int, int, int)` is really like three ints that are all
separate variables. It's just that they are named via the group. It is
NOT like an array, it's more like a struct with fields that have indexes
instead of names.
In order to print them in a loop, based on *runtime* data, you need to
bridge the gap between runtime and compile time. Why? Because a Tuple
does not necessarily contain the same types for every value, so `tup[0]`
might have a different type than `tup[1]`. Because D is strongly-typed,
you need to access these with *compile-time* indexes, so it knows what
type you are using.
Imagine you have a struct, and you want to use a runtime string to
access a given field. This is essentially the same, except it's an index
and not a name.
A typical way to bridge the gap is to use a switch to validate the
runtime variable, and then use the compile-time equivalalent to actually
get the data.
For example, you could write a function like:
```d
void printItem(Tuple!(...) vals, size_t index)
{
theswitch:
final switch(index)
{
static foreach(ctIdx; 0 .. vals.length) {
case ctIdx: writeln(vals[ctIdx]);
break theswitch;
}
}
}
```
Now, if you want to just print them in order, without any runtime
details, you can just use foreach on a tuple and it works (the foreach
variables are compile-time determined).
-Steve
More information about the Digitalmars-d-learn
mailing list