Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
February 07, 2015 Using "reduce" with user types | ||||
---|---|---|---|---|
| ||||
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. |
February 07, 2015 Re: Using "reduce" with user types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kadir Erdem Demir | 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. |
February 07, 2015 Re: Using "reduce" with user types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | > 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
|
February 07, 2015 Re: Using "reduce" with user types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kadir Erdem Demir | 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 |
February 07, 2015 Re: Using "reduce" with user types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kadir Erdem Demir | 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.
|
Copyright © 1999-2021 by the D Language Foundation