On 07/04/2016 11:07 PM, Miguel L wrote:

> struct A
> {
> int x;
> int y;
> }

> would be the best way to get an array of x or y component of my_array?

The simplest is to pick the element by std.algorithm.map:

import std.stdio;
import std.range;
import std.array;
import std.algorithm;

struct A {
    int x;
    int y;
}

void main() {
    A[] my_array = iota(3)
                   .map!(i => A(i, 11 * i))
                   .array;

    writeln("The whole array:");
    writeln(my_array);

    writeln("Just the x members");
    auto xs = my_array.map!(a => a.x);
    writeln(xs);

    writeln("Just the y members");
    auto ys = my_array.map!(a => a.y);
    writeln(ys);
}

Prints

The whole array:
[A(0, 0), A(1, 11), A(2, 22)]
Just the x members
[0, 1, 2]
Just the y members
[0, 11, 22]

map has a shortcut: If there is a function foo that takes A, then you can do just this:

    writeln(my_array.map!foo);

(foo can be a member function or a non-member function.)

With the great risk of polluting the namespace, here is a draft of creating non-member accessor functions automatically:

string memberAccessors(T)() {
    import std.string;
    string accessors;

    foreach(m; __traits(allMembers, T)) {
accessors ~= format("auto %s(%s a) { return a.%s; }\n", m, T.stringof, m);
    }

    return accessors;
}

mixin(memberAccessors!A);

That generates and mixes in accessor functions for each member. A pragma(msg) can show what is generated:

pragma(msg, memberAccessors!A);

Prints at compile time:

auto x(A a) { return a.x; }
auto y(A a) { return a.y; }

(Crazy idea. :) )

But then, it's as simple as the following:

    writeln(my_array.map!y);

Ali

Reply via email to