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.

https://www.pythonforbeginners.com/basics/list-comprehensions-in-python

python new_range = [i + i for i in range(5) if i % 2 == 0]

dlang 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.

dlang 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.

```dlang 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.