The OpenD Programming Language

filter

Implements the higher order filter function. The predicate is passed to mir.functional.naryFun, and can either accept a string, or any callable that can be executed via pred(element).

  1. Filter!(naryFun!pred, Range) filter(Range r)
    template filter(alias pred = "a")
    static if(__traits(isSame, naryFun!pred, pred))
    Filter!(naryFun!pred, Range)
    filter
    (
    Range
    )
    (
    Range r
    )
    if (
    isInputRange!Range &&
    !isSlice!Range
    )
  2. auto filter(Slice!(Iterator, N, kind) slice)

Members

Functions

filter
Filter!(naryFun!pred, Range) filter(Range r)
auto filter(Slice!(Iterator, N, kind) slice)

Parameters

pred

Function to apply to each element of range

Return Value

filter!(pred)(range) returns a new range containing only elements x in range for which pred(x) returns true.

Examples

int[] arr = [ 0, 1, 2, 3, 4, 5 ];

// Filter below 3
auto small = filter!(a => a < 3)(arr);
assert(equal(small, [ 0, 1, 2 ]));

// Filter again, but with Uniform Function Call Syntax (UFCS)
auto sum = arr.filter!(a => a < 3);
assert(equal(sum, [ 0, 1, 2 ]));

// Filter with the default predicate
auto nonZeros = arr.filter;
assert(equal(nonZeros, [ 1, 2, 3, 4, 5 ]));

// In combination with concatenation() to span multiple ranges
import mir.ndslice.concatenation;

int[] a = [ 3, -2, 400 ];
int[] b = [ 100, -101, 102 ];
auto r = concatenation(a, b).filter!(a => a > 0);
assert(equal(r, [ 3, 400, 100, 102 ]));

// Mixing convertible types is fair game, too
double[] c = [ 2.5, 3.0 ];
auto r1 = concatenation(c, a, b).filter!(a => cast(int) a != a);
assert(equal(r1, [ 2.5 ]));

N-dimensional filtering

import mir.ndslice.fuse;
import mir.ndslice.topology: byDim, map;

auto matrix =
    [[   3,   -2, 400 ],
     [ 100, -101, 102 ]].fuse;

alias filterPositive = filter!"a > 0";

// filter all elements in the matrix
auto r = filterPositive(matrix);
assert(equal(r, [ 3, 400, 100, 102 ]));

// filter all elements for each row
auto rr = matrix.byDim!0.map!filterPositive;
assert(equal!equal(rr, [ [3, 400], [100, 102] ]));

// filter all elements for each column
auto rc = matrix.byDim!1.map!filterPositive;
assert(equal!equal(rc, [ [3, 100], [], [400, 102] ]));

N-dimensional filtering based on value in specific row/column

import mir.ndslice.fuse;
import mir.ndslice.topology: byDim;

auto matrix =
[[   3,   2, 400 ],
 [ 100, -101, 102 ]].fuse;

// filter row based on value in index 1
auto r1 = matrix.byDim!0.filter!("a[1] > 0");
assert(equal!equal(r1, [ [3, 2, 400] ]));

// filter column based on value in index 1
auto r2 = matrix.byDim!1.filter!("a[1] > 0");
assert(equal!equal(r2, [ [3, 100], [400, 102] ]));

Filter out NaNs

import mir.algorithm.iteration: equal, filter;
import mir.ndslice.slice: sliced;
import std.math.traits: isNaN;

static immutable result1 = [1.0, 2];

double x;
auto y = [1.0, 2, x].sliced;
auto z = y.filter!(a => !isNaN(a));
assert(z.equal(result1));

Filter out NaNs by row and by column

import mir.algorithm.iteration: equal, filter;
import mir.ndslice.fuse: fuse;
import mir.ndslice.topology: byDim, map;
import std.math.traits: isNaN;

static immutable result1 = [[1.0, 2], [3.0, 4, 5]];
static immutable result2 = [[1.0, 3], [2.0, 4], [5.0]];

double x;
auto y = [[1.0, 2, x], [3.0, 4, 5]].fuse;

// by row
auto z1 = y.byDim!0.map!(filter!(a => !isNaN(a)));
assert(z1.equal!equal(result1));
// by column
auto z2 = y.byDim!1.map!(filter!(a => !isNaN(a)));
assert(z2.equal!equal(result2));

Filter entire rows/columns that have NaNs

import mir.algorithm.iteration: equal, filter;
import mir.ndslice.fuse: fuse;
import mir.ndslice.topology: byDim, map;
import std.math.traits: isNaN;

static immutable result1 = [[3.0, 4, 5]];
static immutable result2 = [[1.0, 3], [2.0, 4]];

double x;
auto y = [[1.0, 2, x], [3.0, 4, 5]].fuse;

// by row
auto z1 = y.byDim!0.filter!(a => a.all!(b => !isNaN(b)));
assert(z1.equal!equal(result1));
// by column
auto z2 = y.byDim!1.filter!(a => a.all!(b => !isNaN(b)));
assert(z2.equal!equal(result2));

See Also

Filter (higher-order function) Note: User and library code MUST call empty method ahead each call of pair or one of front and popFront methods.

Meta