Thread overview
Convert array of tuples into array of arrays.
Aug 31, 2022
musculus
Aug 31, 2022
Nick Treleaven
Aug 31, 2022
Ali Çehreli
Sep 01, 2022
Salih Dincer
August 31, 2022

Hi. I have an array of tuples that I would like to convert to an array of arrays.
All of the elements in the tuples have matching types (string).
How would I go about doing this? Thanks!

August 31, 2022

On Wednesday, 31 August 2022 at 14:34:50 UTC, musculus wrote:

>

Hi. I have an array of tuples that I would like to convert to an array of arrays.
All of the elements in the tuples have matching types (string).
How would I go about doing this? Thanks!

Assuming std.typecons.Tuple, you can use [tup.expand] to make an array from a tuple.
If you mean a value sequence, you can use [valSeq].

August 31, 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

September 01, 2022

On Wednesday, 31 August 2022 at 17:26:56 UTC, Ali Çehreli wrote:

>

[...] 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:

I really like the generic methods. Because we can use enums for field names; e.g:

import std;

void main()
{
  enum {
    key = "productCode",
    val = "priceDolar"
  }

  auto makeTestTuple(int i)
  {
    return tuple!(key, val)((i * 2).to!string,
                   (double(i) / 10).to!string);
  }

  auto memberTuple(string member, T)(T tuples)
  {
    return mixin("tuples." ~ member);
  }

  auto tuples = 1.iota(10)
                 .map!makeTestTuple
                 .array;

  string[string] myList;

  foreach(t; tuples)
  {
      const keys = memberTuple!key(t);
    myList[keys] = memberTuple!val(t);
    keys.writeln(": ", myList[keys]);
  }
} /*
2: 0.1
4: 0.2
6: 0.3
8: 0.4
10: 0.5
12: 0.6
14: 0.7
16: 0.8
18: 0.9
*/

SDB@79