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

Reply via email to