I didn't want to confuse function mapping and dictionaries, so I decided to include reduce.
map is a range (list) based function which applies an operation to each element and their result is a range which lazily applies the operation.
I haven't been referencing how other languages apply a solution, but as this started with Python and their list comprehension is an interesting approach to this.
new_range = [i + i for i in range(5) if i % 2 == 0]
import std.range; auto new_range = iota(5) .filter!(i => i % 2 == 0) .map!(i => i + i);
Putting aside the strange name
iota the structure is similar. Personally I'd argue D is more clear about the operation order.
import std.range; auto new_range = iota(5) .map!(i => i + i) .filter!(i => i % 2 == 0);
In the first situation filtering came before the operation, filtering after has no value since two odds make an even. In Python order of operation is a spiral like C function pointers.
reduce is an operation on a range which produces a single result.
import std.algorithm; import std.range; assert( iota(5).fold!((a, b) => a + b) == 1 + 2 + 3 + 4);
I realize my example uses
fold rather than
reduce. This has many more names, but I chose fold in the example as this provides better argument order in chained expressions.