Convert array of tuples into array of arrays.
Ali Çehreli
acehreli at yahoo.com
Wed Aug 31 17:26:56 UTC 2022
On 8/31/22 07:34, musculus wrote:
> Hi. I have an array of tuples that I would like to convert to an array
> of arrays.
I misunderstood as well and wrote the following program which makes
separate arrays. You can make an array of arrays from those with the
following syntax:
auto arrayOfArrays = [ keys, values ];
Then I wrote a more general program after this first one:
// Compiles slow but is convenient
import std;
auto makeTestTuple(int i) {
return tuple!("key", "value")((i * 2).to!string,
(double(i) / 10).to!string);
}
void main() {
auto tuples = iota(10)
.map!makeTestTuple
.array;
string[] keys;
string[] values;
writeln("Imperative:");
foreach (t; tuples) {
keys ~= t.key;
values ~= t.value;
}
writeln(keys);
writeln(values);
writeln("Alternative:");
keys = tuples.map!(t => t.key).array;
values = tuples.map!(t => t.value).array;
writeln(keys);
writeln(values);
writeln("More generic:");
keys = tuples.memberArray!"key";
values = tuples.memberArray!"value";
writeln(keys);
writeln(values);
}
auto memberArray(string member, T)(T[] tuples) {
return tuples.map!(t => mixin("t." ~ member)).array;
}
Here is the second program to have fun and "competitive advantage" with
D. (That phrase came up recently, so I remembered it here. :) )
// Compiles slow but is convenient
import std;
auto makeTestTuple(int i) {
return tuple!("key", "value", "somethingElse")(
(i * 2).to!string,
(double(i) / 10).to!string,
i * i);
}
mixin template matchingMember(string name, T) {
mixin (T.stringof ~ "[] " ~ name ~ ';');
}
template TupleMemberArrays(T) {
alias types = T.Types;
alias fieldNames = T.fieldNames;
enum memberCount = types.length;
struct TupleMemberArrays {
static foreach (i; 0 .. memberCount) {
mixin matchingMember!(fieldNames[i], types[i]);
}
this(T[] tuples) {
foreach (t; tuples) {
static foreach (i; 0 .. memberCount) {
mixin (format!q{
%s ~= t.%s = t[%s];
}(fieldNames[i], fieldNames[i], i));
}
}
}
}
}
void main() {
auto tuples = iota(10)
.map!makeTestTuple
.array;
alias S = TupleMemberArrays!(ElementType!(typeof(tuples)));
auto s = S(tuples);
writeln(s.key);
writeln(s.value);
writeln(s.somethingElse);
}
That second program defines a type that matches the members of a tuple.
Given a tuple with member names "key", "value", and "somethingElse"; and
types string, string, int; it generates a struct similar to the following:
struct YourAliasHere {
string[] key;
string[] value;
int[] somethingElse;
}
Limitation: That implementation uses field names, which not all tuples
use. But it can be changed to generate names file field0, field1, etc.
when needed.
Ali
More information about the Digitalmars-d-learn
mailing list