From [Tuple!(A,B), ...] to Tuple!(A[], B[])
Simen Kjærås
simen.kjaras at gmail.com
Mon Feb 17 12:11:38 UTC 2020
On Monday, 17 February 2020 at 11:51:52 UTC, FeepingCreature
wrote:
> Here you go:
>
> import std;
>
> // extract the types that make up the tuple
> auto transposeTuple(T : Tuple!Types[], Types...)(T tuples)
> {
> // templated function that extracts the ith field of an
> array of tuples as an array
> auto extractArray(int i)()
> {
> return tuples.map!(a => a[i]).array;
> }
> // return tuple of calls to extractArray, one for each
> tuple index
> return tuple(staticMap!(extractArray,
> aliasSeqOf!(Types.length.iota)));
> }
>
> void main() {
> Tuple!(int, double)[] array;
> array ~= tuple(1, 2.0);
> array ~= tuple(3, 4.0);
> Tuple!(int[], double[]) tuple = array.transposeTuple;
> assert(tuple[0] == [1, 3]);
> assert(tuple[1] == [2.0, 4.0]);
> }
One tiny thing: the above fails for tuples with named fields,
like Tuple!(int, "a", string "b"). This code handles that case,
and preserves field names:
import std.meta : staticMap, aliasSeqOf;
import std.typecons : Tuple;
import std.range : array, iota;
import std.algorithm : map;
alias ToArray(T) = T[];
alias ToArray(T...) = T;
alias ToArrayTuple(T : Tuple!U, U...) =
Tuple!(staticMap!(ToArray, U));
auto transpose(T : Tuple!U, U...)(T[] arr) {
auto extract(int i)() { return arr.map!(a => a[i]).array; }
return ToArrayTuple!T(staticMap!(extract,
aliasSeqOf!(T.Types.length.iota)));
}
unittest {
alias T = Tuple!(int, "a", string, "b");
auto a = [T(1, "a"), T(2, "b")];
assert(a.transpose.a == [1, 2]);
assert(a.transpose.b == ["a", "b"]);
}
--
Simen
More information about the Digitalmars-d-learn
mailing list