Using reduce with user types

2015-02-07 Thread Kadir Erdem Demir via Digitalmars-d-learn

I can use filter algorithm with my types easily.

struct A
{
string value;
int count;
}


void main(  string[] args )
{
A[] aArr;
aArr  ~= A(HTTP, 3);
aArr  ~= A(HTTPS, 2);
aArr  ~= A(UNKNOWN_TCP, 4);
aArr.filter!( a = a.count == 2);

But I couldn't compile when I want to use reduce algorithm. I 
simply want to get the sum of count variables inside of A[]. 	


auto sum = aArr.reduce!((a,b) = a.count + b.count);

The line above gives

C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(770): 
Error: cannot implicitly convert expression (__lambda3(result, 
front(_param_1))) of type int to A
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(791): 
Error: template instance app.main.reduce!((a, b) = a.count + 
b.count).reduce!(A, A[]) error instantiating

source\app.d(363):instantiated from here: reduce!(A[])

How can I achieve summing count variables inside A[]?

Best Regards
Kadir Erdem Demir

Ps: The problem caused by my lack of D basics I admit, the reason 
I can't look up references more  before ask question I am in a 
bit tight schedule. Sorry for my dummy questions.


Re: Using reduce with user types

2015-02-07 Thread Rikki Cattermole via Digitalmars-d-learn

On 8/02/2015 1:47 a.m., Kadir Erdem Demir wrote:

I can use filter algorithm with my types easily.

struct A
{
 string value;
 int count;
}


void main(  string[] args )
{
 A[] aArr;
 aArr  ~= A(HTTP, 3);
 aArr  ~= A(HTTPS, 2);
 aArr  ~= A(UNKNOWN_TCP, 4);
 aArr.filter!( a = a.count == 2);

But I couldn't compile when I want to use reduce algorithm. I simply
want to get the sum of count variables inside of A[].

 auto sum = aArr.reduce!((a,b) = a.count + b.count);

The line above gives

C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(770): Error:
cannot implicitly convert expression (__lambda3(result,
front(_param_1))) of type int to A
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(791): Error:
template instance app.main.reduce!((a, b) = a.count +
b.count).reduce!(A, A[]) error instantiating
source\app.d(363):instantiated from here: reduce!(A[])

How can I achieve summing count variables inside A[]?

Best Regards
Kadir Erdem Demir

Ps: The problem caused by my lack of D basics I admit, the reason I
can't look up references more  before ask question I am in a bit tight
schedule. Sorry for my dummy questions.


auto sum = aArr.map!`a.count`.reduce!((a,b) = a + b);

Not much difference.
I tried sum instead of reduce, but it didn't work. Wouldn't matter much 
as it is the same thing pretty much anyway.


Re: Using reduce with user types

2015-02-07 Thread FG via Digitalmars-d-learn

On 2015-02-07 at 13:47, Kadir Erdem Demir wrote:


 auto sum = aArr.reduce!((a,b) = a.count + b.count);

The line above gives

C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(770): Error: cannot 
implicitly convert expression (__lambda3(result, front(_param_1))) of type int 
to A
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(791): Error: template 
instance app.main.reduce!((a, b) = a.count + b.count).reduce!(A, A[]) error 
instantiating
source\app.d(363):instantiated from here: reduce!(A[])



// auto sum = aArr.reduce!((a,b) = a.count + b.count); // Wrong

auto sum = reduce!((a, b) = a + b.count)(0, aArr); // Good


See here: http://dlang.org/phobos/std_algorithm.html#.reduce


Re: Using reduce with user types

2015-02-07 Thread Kadir Erdem Demir via Digitalmars-d-learn

auto sum = aArr.map!`a.count`.reduce!((a,b) = a + b);


Rikki Thanks a lot. It works.

Function map!a.count(aArr) surprises me a little.
Because when I read std.algorithm reference: `Implements the 
homonym function (also known as transform)`.


Which reminds me C++ transform and it will never used for 
returning a element of the struct.  I expect transform to modify 
the elements of the range but in D it seem to me it also used 
traversing the elements.


How can I imagine what map does in my mind, because it doesn't 
matches with the transform concept in my mind?


Regards
Kadir Erdem


Re: Using reduce with user types

2015-02-07 Thread Meta via Digitalmars-d-learn
On Saturday, 7 February 2015 at 13:38:00 UTC, Kadir Erdem Demir 
wrote:
How can I imagine what map does in my mind, because it 
doesn't matches with the transform concept in my mind?


You can think of map as taking a range of something (in this 
case, an array of A), and calling a user-supplied function on 
each element in that range. The user-supplied function is a 
function that describes how to map each value in the range to a 
result. In your case, the function defines how to map from an A 
to its `count` member variable (it is a function of type A-int).


All aArr.map!`a.count` means is that for each A in aArr, return 
its `count` member. map!`a.count` is some syntax sugar D has to 
make function calls shorter; It expands to the following:


aArr.map!((A a) {
return a.count;
})

The main difference between `map` in D and `transform` in C++ is, 
I believe, twofold. First off, `transform` is eager, meaning it 
does as much work as possible as son as possible. On the other 
hand, `map` does as little work as possible as late as possible. 
For the following code:


iota(10).map!(n = writeln(n)).take(5).array

Only 0 1 2 3 4 will be printed, as map is lazy and will not do 
work it doesn't have to.


Second of all, map returns a range that is the result of applying 
the supplied function to each element of aArr. C++'s tranform 
copies the result to another user-supplied range. If you wanted 
the equivalent of transform in C++, you could do this:


auto result = new int[](10);
iota(10).map!(n = n + 1).copy(result)

And result will be filled with the results of map.