Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
February 17, 2020 From [Tuple!(A,B), ...] to Tuple!(A[], B[]) | ||||
---|---|---|---|---|
| ||||
Hi all, There's something in Phobos for that? Thank you |
February 17, 2020 Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[]) | ||||
---|---|---|---|---|
| ||||
Posted in reply to foozzer | On Monday, 17 February 2020 at 11:07:33 UTC, foozzer wrote:
> Hi all,
>
> There's something in Phobos for that?
>
> Thank you
import std.meta : staticMap;
import std.typecons : Tuple;
// Turn types into arrays
alias ToArray(T) = T[];
// Leave everything else the same
alias ToArray(T...) = T;
// Now apply the above to each element of the Tuple template args:
alias ToArrayTuple(T : Tuple!U, U...) = Tuple!(staticMap!(ToArray, U));
unittest {
alias A = Tuple!(int, string);
assert(is(ToArrayTuple!A == Tuple!(int[], string[])));
alias B = Tuple!(int, "a", string, "b");
assert(is(ToArrayTuple!B == Tuple!(int[], "a", string[], "b")));
}
--
Simen
|
February 17, 2020 Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[]) | ||||
---|---|---|---|---|
| ||||
Posted in reply to foozzer | On Monday, 17 February 2020 at 11:07:33 UTC, foozzer wrote: > Hi all, > > There's something in Phobos for that? > > Thank you 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]); } |
February 17, 2020 Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[]) | ||||
---|---|---|---|---|
| ||||
Posted in reply to FeepingCreature | On Monday, 17 February 2020 at 11:51:52 UTC, FeepingCreature wrote:
> On Monday, 17 February 2020 at 11:07:33 UTC, foozzer wrote:
>> Hi all,
>>
>> There's something in Phobos for that?
>>
>> Thank you
>
> 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]);
> }
^^ Do what he said - I misread the title. :)
--
Simen
|
February 17, 2020 Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[]) | ||||
---|---|---|---|---|
| ||||
Posted in reply to FeepingCreature | 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 |
February 17, 2020 Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[]) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Monday, 17 February 2020 at 12:11:38 UTC, Simen Kjærås wrote:
> On Monday, 17 February 2020 at 11:51:52 UTC, FeepingCreature wrote:
>> [...]
>
> 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:
>
> [...]
Thank you all
|
Copyright © 1999-2021 by the D Language Foundation