Most elegant way for split array of struct into components
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jul 5 00:33:40 PDT 2016
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
More information about the Digitalmars-d-learn
mailing list