Result of std.algorithm.map

Can someone say what std.algorithm.map returns? (a link to some documentation page would be greatly appreciated) From the error message, its result is of type Result

 ulong[] x = [1,2,3]; ulong[] y = std.algorithm.map!"a"(x); // Error: cannot implicitly convert <..> of type Result to ulong[] 

At http://dlang.org/phobos/std_algorithm.html#map there is little information about this:

 The call map!(fun)(range) returns a range of which elements are obtained by applying fun(x) left to right for all x in range 

From this it is not clear what I can or cannot do with this.

+6
source share
3 answers

You do not need to know or care that std.algorithm.map goes back beyond the fact that it is a range of the same genre as the one that went through (forward, bidirectional, random, etc.). Thus, most range-based functions. They almost always return either a new range that wraps the one that passed, or the same type of range that was passed (for example, map does the first, find is the last). Use auto :

 ulong[] x = [1, 2, 3]; auto y = map!"a"(x); 

The range returned by map is lazy. It does nothing until you iterate over it (then it calls this function in each subsequent front base range). It is more efficient this way (and also allows endless ranges). The exact type of return depends on the type of range in which you traveled and is local to map so that you cannot create it directly. You need to either use auto to type or typeof to get the type:

 typeof(map!"a"(x)) y = map!"a"(x); 

However, you usually use typeof when you need a variable that you cannot initialize directly. auto is almost always the way to go.

If you need to create an array from the map result (or from any other range), use std.array.array :

 ulong[] y = array(map!"a"(x)); 

If you know little about ranges, you should probably read this . Unfortunately, there is currently no article on dlang.org explaining ranges, but this link is for a chapter in a book that one of the D community members wrote in Turkish and translated into English, and it covers ranges quite well.

EDIT

Walter Bright recently wrote an article about types that are local to a function, but returns a function that can also help you enlighten. They even get a cool name: Voldemort Types in D

+7
source

The range of results is lazy; it does not represent the end result.

It can be turned into an array if you import std.array and end it as follows:

 ulong[] y = array(std.algorithm.map!"a"(x)); 

or

 ulong[] y = std.algorithm.map!"a"(x).array; 

if you are using dmd 2.059 or later

The result of the map can also be looped directly using foreach:

 auto result = std.algorithm.map!"a"(x); foreach (element; result) writeln(to!string(element)); 
+3
source

Result is a type inside map() that cannot be called because it is a Voldemort Type .

The actual source code in Phobos looks something like this:

 template map(fun...) if (fun.length >= 1) { auto map(Range)(Range r) if (isInputRange!(Unqual!Range)) { //... struct Result { //... } return Result(r); } } 

If you study the source code, you will notice that Result is nothing more than a range: it has the usual popFront() and empty() methods and other methods depending on the type of range that needs to be returned. If you use type inference,

 auto r = map!("a*a")(data); 

r will be typed as Result , but you cannot create it directly.

+1
source

Source: https://habr.com/ru/post/914836/


All Articles