Completing C code with D style

Ali Çehreli acehreli at yahoo.com
Wed Nov 3 00:57:38 UTC 2021


On 11/2/21 5:50 PM, Siarhei Siamashka wrote:
> Your code can be changed to 
> something like this:

And I over-engineered it. :)

import std.stdio;
import std.algorithm;
import std.range;
import std.exception;
import std.format;

// A readable name; corresponds to C's typedef
alias FilterFunction = bool function(int);

// These are our filters; they will be initialized not right
// where they are defined but in a following 'shared static
// this()'. (This is a current D implementation issue.)
immutable FilterFunction[string] negativityFilters;
immutable FilterFunction[string] evennessFilters;

// 'shared static this()' blocks are executed before main()
// is executed.
shared static this() {
   const matchAll = (int _) { return true; };

   negativityFilters = [
     "negatives" : (int i) { return i <= 0; },
     "positives" : (int i) { return i >= 0; },
     "both" : matchAll,
   ];

   evennessFilters = [
     "evens" : (int i) { return (i % 2) == 0; },
     "odds" : (int i) { return (i % 2) == 1; },
     "both" : matchAll,
   ];
}

// Picks the filter that corresponds to user input
FilterFunction pickFilter(const(FilterFunction[string]) filters) {
   // The full names of filters e.g. [ "evens", "odds", "both" ]
   auto fulls = filters.byKey.array.sort;

   // The first letters of the names e.g. [ 'b', 'e', 'o' ]
   auto shorts = fulls.map!(key => key.front);

   // A mapping from short to full name e.g. 'b' -> "both"
   auto shortToFull = assocArray(shorts, fulls);

   // Prompt the user by combining the short and full names
   writef!"Would you like in list (%-(%s, %))? "(
     zip(shorts, fulls).map!(z => format!"%s=%s"(z[0], z[1])));

   char c;
   readf(" %c", &c);
   enforce(c in shortToFull, format!"'%s' is not a valid option"(c));

   const full = shortToFull[c];
   return filters[full];
}

// Picks filters according to user input
FilterFunction[] pickFilters() {
   return [ negativityFilters, evennessFilters ].map!pickFilter.array;
}

// The main logic of the program
void run() {
   auto numbers = [ -3, 14, 47, -49, -30, 15, 4, -82, 99, 26 ];

   auto filters = pickFilters();
   auto selection = numbers.filter!(n => filters.all!(f => f(n)));

   writefln!"%-(%s\n%)"(selection);
}

int main() {
   try {
     run();
     return 0;

   } catch (Exception e) {
     stderr.writefln!"ERROR: %s"(e.msg);
     return 1;
   }
}

Ali


More information about the Digitalmars-d-learn mailing list