Thread overview
Converting array in to aliased tuple type.
Dec 25, 2017
aliak
Dec 25, 2017
Mengu
Dec 25, 2017
aliak
Dec 25, 2017
visitor
Dec 25, 2017
visitor
Dec 25, 2017
aliak
Dec 25, 2017
visitor
Dec 25, 2017
visitor
December 25, 2017
Hi, been looking for a way to convert an array to a tuple, but can't seem to find one. Is there one?

Looking for something like:

alias Point = Tuple!(int, "x", int, "y");
enum data = "1,2:8,9";
auto points = data
  .split(':')
  .map!(a => a
    .split(',')
    .map!(to!int)
  )
  .map!Point; // <-- this works if you do `.map!(a => Point(a[0], a[1]));` instead

Cheers!

December 25, 2017
On Monday, 25 December 2017 at 12:03:32 UTC, aliak wrote:
> Hi, been looking for a way to convert an array to a tuple, but can't seem to find one. Is there one?
>
> Looking for something like:
>
> alias Point = Tuple!(int, "x", int, "y");
> enum data = "1,2:8,9";
> auto points = data
>   .split(':')
>   .map!(a => a
>     .split(',')
>     .map!(to!int)
>   )
>   .map!Point; // <-- this works if you do `.map!(a => Point(a[0], a[1]));` instead
>
> Cheers!

hi aliak

since Point is a Tuple and does not have a constructor that takes a list of integers (int[]), you should have a helper function.

    import std.stdio: writeln;
    import std.string: split;
    import std.algorithm: map;
    import std.typecons: Tuple;
    import std.conv: to;

    alias Point = Tuple!(int, "x", int, "y");
    enum data = "1,2:8,9";
    alias makePoint = (auto ref points) => Point(points[0], points[1]);
    alias convertToInt = (string parts) => parts.split(',').map!(to!int);
    auto points = data.split(':').map!(convertToInt).map!(makePoint);

    writeln(points);
December 25, 2017
On Monday, 25 December 2017 at 14:08:08 UTC, Mengu wrote:
>
> since Point is a Tuple and does not have a constructor that takes a list of integers (int[]), you should have a helper function.

Aukay :(

I was kind of hoping for some magical D variadic alias template on Tuple or something that will just deconstruct the arguments in to tuple components.


December 25, 2017
On Monday, 25 December 2017 at 15:03:08 UTC, aliak wrote:
> On Monday, 25 December 2017 at 14:08:08 UTC, Mengu wrote:
>>
> I was kind of hoping for some magical D variadic alias template on Tuple or something that will just deconstruct the arguments in to tuple components.

i don't think it's better but :

https://run.dlang.io/is/2rgOzh

December 25, 2017
On Monday, 25 December 2017 at 17:59:54 UTC, visitor wrote:
> On Monday, 25 December 2017 at 15:03:08 UTC, aliak wrote:
>> On Monday, 25 December 2017 at 14:08:08 UTC, Mengu wrote:
>>>
>> I was kind of hoping for some magical D variadic alias template on Tuple or something that will just deconstruct the arguments in to tuple components.
>
> i don't think it's better but :
>
> https://run.dlang.io/is/2rgOzh

oops sorry, compile time ...

import std.stdio, std.string, std.algorithm, std.conv, std.range;
import std.typecons;

alias Point = Tuple!(int, "x", int, "y");
enum data = "1,2:8,9";

auto points = data.split(':')
                  .map!( a => a.split(',').map!(to!int).array )
                  .map!( (da) {
                      int[2] staticArray;
                      foreach (i, el; da)
                          staticArray[i] = el;
                      return staticArray;
                  } )
                  .map!Point ;

void main()
{
    writefln("points : %s", points);
}
December 25, 2017
On Monday, 25 December 2017 at 17:59:54 UTC, visitor wrote:
> On Monday, 25 December 2017 at 15:03:08 UTC, aliak wrote:
>> On Monday, 25 December 2017 at 14:08:08 UTC, Mengu wrote:
>>>
>> I was kind of hoping for some magical D variadic alias template on Tuple or something that will just deconstruct the arguments in to tuple components.
>
> i don't think it's better but :
>
> https://run.dlang.io/is/2rgOzh

Heh, no it's probably not, but interesting! So it does work with a static array. Is it that .array on a range is not able to infer a size and hence produce a static array for the given situation? Is this a D limitation, a logical one or maybe just not implemented yet?

Cheers!
December 25, 2017
On Monday, 25 December 2017 at 21:11:08 UTC, aliak wrote:
> On Monday, 25 December 2017 at 17:59:54 UTC, visitor wrote:
>> On Monday, 25 December 2017 at 15:03:08 UTC, aliak wrote:
>>> On Monday, 25 December 2017 at 14:08:08 UTC, Mengu wrote:
>>>>
>>> I was kind of hoping for some magical D variadic alias template on Tuple or something that will just deconstruct the arguments in to tuple components.
>>
>> i don't think it's better but :
>>
>> https://run.dlang.io/is/2rgOzh
>
> Heh, no it's probably not, but interesting! So it does work with a static array. Is it that .array on a range is not able to infer a size and hence produce a static array for the given situation? Is this a D limitation, a logical one or maybe just not implemented yet?
>
> Cheers!

i don't know the reason, and would be glad to be unlighted :)
There is a Tuple constructor which takes a static array as a param :
https://dlang.org/phobos/std_typecons.html#.Tuple.this.2
i needed to iterate with an index when building the static array later, so i transformed the range (a.split(',').map!(to!int)) into a dynamic array, to do so.
one could use std.range enumerate() instead:

auto points = data.split(':')
                  .map!( a => a.split(',').map!(to!int) )
                  .map!( (a) {
                      int[2] staticArray;
                      foreach (i, el; a.enumerate()) staticArray[i] = el;
                      return staticArray;
                  } )
                  .map!Point;

Cheers

December 25, 2017
On Monday, 25 December 2017 at 21:35:18 UTC, visitor wrote:
> On Monday, 25 December 2017 at 21:11:08 UTC, aliak wrote:
>> On Monday, 25 December 2017 at 17:59:54 UTC, visitor wrote:
>>> On Monday, 25 December 2017 at 15:03:08 UTC, aliak wrote:
>>>> On Monday, 25 December 2017 at 14:08:08 UTC, Mengu wrote:
>>>>>
probably better this way

int[2] tmp;
auto points = data.split(':')
                  .map!( (a) {
                      a.split(',').map!(to!int).enumerate()
                      .each!( (i, el) => tmp[i] = el );
                      return Point(tmp);
                  } );