Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

2020-02-17 Thread foozzer via Digitalmars-d-learn

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


Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

2020-02-17 Thread Simen Kjærås via Digitalmars-d-learn
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


Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

2020-02-17 Thread FeepingCreature via Digitalmars-d-learn

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]);
}


Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

2020-02-17 Thread Simen Kjærås via Digitalmars-d-learn
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


Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

2020-02-17 Thread Simen Kjærås via Digitalmars-d-learn

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


From [Tuple!(A,B), ...] to Tuple!(A[], B[])

2020-02-17 Thread foozzer via Digitalmars-d-learn

Hi all,

There's something in Phobos for that?

Thank you