Chaining std.algorithm

Ali Çehreli acehreli at yahoo.com
Sun Dec 15 21:46:25 PST 2013


On 12/15/2013 08:42 PM, John Carter wrote:

 > So I have an array of data...
 >   struct romanSystemData {
 >     string digit;
 >     uint   value;
 >     ulong  regionIndex;
 >     ulong  previous;
 > };
 >
 > immutable romanSystemData romanSystem[] = [
 >     {"" ,    0, 0, 0},//0
 >     {"I",    1, 0, 0},//1 8-7
 >     {"V",    5, 1, 1},//2 8-6
 >     {"X",   10, 1, 2},//3 8-5
 >     {"L",   50, 3, 3},//4 8-4
 >     {"C",  100, 3, 4},//5 8-3
 >     {"D",  500, 5, 5},//6 8-2
 >     {"M", 1000, 5, 6} //7 8-1
 > ];
 >
 > I'm happy I can use this look up table ...
 >
 > assert( 10 == find!"(a.digit == b)"( romanSystem, "X").front.value);

The rule is to look for a range (e.g. an array) to be the first argument 
that is passed to a function. Then, take that parameter out and apply 
the function to it as if the function is a member function of that 
range. This is called UFCS (universal function call syntax).

For example, since romanSystem is the first argument to the function 
call find!"(a.digit == b)", write it like this:

     romanSystem.find!"(a.digit == b)"("X")

 > Now I'm sure I can use std.algorithm map to convert say a string of
 > characters "IVXLCDM" into an array [1,5,10,50,100,500,1000]
 >
 > but somehow D template instantiation syntax is flumoxing me.
 >
 > When I try use find in map!"find!""" dmd whinges like crazy at me.
 >
 > How do you nest these things?

The good thing is, find and many other std.algorithm functions return 
ranges themselves. So, when passing those ranges as first arguments to 
other functions, the same rule applies:

     foo!F(bar!B(myRange, 'b'), 'f');

becomes (applying the rule from inside out in two steps):

1)    foo!F(myRange.bar!B('b'), 'f');

2)    myRange.bar!B('b').foo!F('f');

Ali



More information about the Digitalmars-d-learn mailing list