Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 11, 2014 std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
I have this test code: struct Thing { uint x; } void main(){ uint[] ar1 = [1, 2, 3, 4, 5]; auto min1 = ar1.reduce!((a,b) => a < b); writefln("%s", min1); // prints 1 as expected Thing[] ar2 = [Thing(1), Thing(2), Thing(4)]; auto min2 = ar2.reduce!((a,b) => a.x < b.x); // <- Wont Compile writefln("%s", min2); } The line with "Wont Compile" on it has this error message: /usr/include/dmd/phobos/std/algorithm.d(770): Error: cannot implicitly convert expression (__lambda2(result, front(_param_1))) of type bool to Thing /usr/include/dmd/phobos/std/algorithm.d(791): Error: template instance t.main.reduce!((a, b) => a.x < b.x).reduce!(Thing, Thing[]) error instantiating t.d(16): instantiated from here: reduce!(Thing[]) Any idea what I'm doing wrong here? To me, the operation on ar2 should be pretty much identical to ar1, except for the use of the struct. |
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin | On Thursday, 11 September 2014 at 13:06:05 UTC, Colin wrote:
> I have this test code:
>
> struct Thing {
> uint x;
> }
>
> void main(){
> uint[] ar1 = [1, 2, 3, 4, 5];
> auto min1 = ar1.reduce!((a,b) => a < b);
> writefln("%s", min1); // prints 1 as expected
>
> Thing[] ar2 = [Thing(1), Thing(2), Thing(4)];
> auto min2 = ar2.reduce!((a,b) => a.x < b.x); // <- Wont Compile
> writefln("%s", min2);
> }
>
> The line with "Wont Compile" on it has this error message:
> /usr/include/dmd/phobos/std/algorithm.d(770): Error: cannot implicitly convert expression (__lambda2(result, front(_param_1))) of type bool to Thing
> /usr/include/dmd/phobos/std/algorithm.d(791): Error: template instance t.main.reduce!((a, b) => a.x < b.x).reduce!(Thing, Thing[]) error instantiating
> t.d(16): instantiated from here: reduce!(Thing[])
>
>
> Any idea what I'm doing wrong here?
> To me, the operation on ar2 should be pretty much identical to ar1, except for the use of the struct.
You are try to put uint to Thing. This is corect version:
import std.stdio;
import std.algorithm;
struct Thing {
uint x;
}
void main(){
uint[] ar1 = [1, 2, 3, 4, 5];
auto min1 = ar1.reduce!((a,b) => a < b);
writefln("%s", min1); // prints 1 as expected
Thing[] ar2 = [Thing(1), Thing(2), Thing(4)];
auto min2 = ar2.reduce!((a,b) => a.x < b.x ? a : b); // <-
Wont Compile
writefln("%s", min2);
}
|
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin | On Thursday, 11 September 2014 at 13:06:05 UTC, Colin wrote: > I have this test code: > > struct Thing { > uint x; > } > > void main(){ > uint[] ar1 = [1, 2, 3, 4, 5]; > auto min1 = ar1.reduce!((a,b) => a < b); > writefln("%s", min1); // prints 1 as expected > > Thing[] ar2 = [Thing(1), Thing(2), Thing(4)]; > auto min2 = ar2.reduce!((a,b) => a.x < b.x); // <- Wont Compile > writefln("%s", min2); > } > > The line with "Wont Compile" on it has this error message: > /usr/include/dmd/phobos/std/algorithm.d(770): Error: cannot implicitly convert expression (__lambda2(result, front(_param_1))) of type bool to Thing > /usr/include/dmd/phobos/std/algorithm.d(791): Error: template instance t.main.reduce!((a, b) => a.x < b.x).reduce!(Thing, Thing[]) error instantiating > t.d(16): instantiated from here: reduce!(Thing[]) > > > Any idea what I'm doing wrong here? > To me, the operation on ar2 should be pretty much identical to ar1, except for the use of the struct. I think you want to use `filter()` (for both Thing and uint), not `reduce()`. The former produces a range with only the elements that match the predicate, while the latter produces _one_ element according to the given rules, e.g. my_int_array.reduce!((result,a) => result+a); produces the sum of all elements. In your example, the first use only compiles because `bool` happens to be implicitly convertible to `uint`. |
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Thursday, 11 September 2014 at 13:28:37 UTC, Marc Schütz wrote: > On Thursday, 11 September 2014 at 13:06:05 UTC, Colin wrote: >> I have this test code: >> >> struct Thing { >> uint x; >> } >> >> void main(){ >> uint[] ar1 = [1, 2, 3, 4, 5]; >> auto min1 = ar1.reduce!((a,b) => a < b); >> writefln("%s", min1); // prints 1 as expected >> >> Thing[] ar2 = [Thing(1), Thing(2), Thing(4)]; >> auto min2 = ar2.reduce!((a,b) => a.x < b.x); // <- Wont Compile >> writefln("%s", min2); >> } >> >> The line with "Wont Compile" on it has this error message: >> /usr/include/dmd/phobos/std/algorithm.d(770): Error: cannot implicitly convert expression (__lambda2(result, front(_param_1))) of type bool to Thing >> /usr/include/dmd/phobos/std/algorithm.d(791): Error: template instance t.main.reduce!((a, b) => a.x < b.x).reduce!(Thing, Thing[]) error instantiating >> t.d(16): instantiated from here: reduce!(Thing[]) >> >> >> Any idea what I'm doing wrong here? >> To me, the operation on ar2 should be pretty much identical to ar1, except for the use of the struct. > > I think you want to use `filter()` (for both Thing and uint), not `reduce()`. Scratch that, `filter()` doesn't make sense here, of course. The rest is still valid: > The former produces a range with only the elements that match the predicate, while the latter produces _one_ element according to the given rules, e.g. > > my_int_array.reduce!((result,a) => result+a); > > produces the sum of all elements. In your example, the first use only compiles because `bool` happens to be implicitly convertible to `uint`. |
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | On Thursday, 11 September 2014 at 13:27:39 UTC, Daniel Kozak wrote:
> On Thursday, 11 September 2014 at 13:06:05 UTC, Colin wrote:
>> I have this test code:
>>
>> struct Thing {
>> uint x;
>> }
>>
>> void main(){
>> uint[] ar1 = [1, 2, 3, 4, 5];
>> auto min1 = ar1.reduce!((a,b) => a < b);
>> writefln("%s", min1); // prints 1 as expected
>>
>> Thing[] ar2 = [Thing(1), Thing(2), Thing(4)];
>> auto min2 = ar2.reduce!((a,b) => a.x < b.x); // <- Wont Compile
>> writefln("%s", min2);
>> }
>>
>> The line with "Wont Compile" on it has this error message:
>> /usr/include/dmd/phobos/std/algorithm.d(770): Error: cannot implicitly convert expression (__lambda2(result, front(_param_1))) of type bool to Thing
>> /usr/include/dmd/phobos/std/algorithm.d(791): Error: template instance t.main.reduce!((a, b) => a.x < b.x).reduce!(Thing, Thing[]) error instantiating
>> t.d(16): instantiated from here: reduce!(Thing[])
>>
>>
>> Any idea what I'm doing wrong here?
>> To me, the operation on ar2 should be pretty much identical to ar1, except for the use of the struct.
>
>
> You are try to put uint to Thing. This is corect version:
>
> import std.stdio;
> import std.algorithm;
>
> struct Thing {
> uint x;
> }
>
> void main(){
> uint[] ar1 = [1, 2, 3, 4, 5];
> auto min1 = ar1.reduce!((a,b) => a < b);
> writefln("%s", min1); // prints 1 as expected
>
> Thing[] ar2 = [Thing(1), Thing(2), Thing(4)];
> auto min2 = ar2.reduce!((a,b) => a.x < b.x ? a : b); // <-
> Wont Compile
> writefln("%s", min2);
> }
Ah ok. I get it.
Thanks daniel!
|
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin | On Thursday, 11 September 2014 at 14:18:31 UTC, Colin wrote:
>
> Ah ok. I get it.
>
> Thanks daniel!
a quiet better version:
import std.stdio;
import std.algorithm;
struct Thing {
uint x;
alias x this;
}
void main(){
uint[] ar1 = [1, 2, 3, 4, 5];
auto min1 = ar1.reduce!((a,b) => min(a,b));
writefln("%s", min1);
Thing[] ar2 = [Thing(1), Thing(2), Thing(4)];
auto min2 = ar2.reduce!((a,b) => min(a,b));
writefln("%s", min2);
}
|
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | On Thursday, 11 September 2014 at 14:39:53 UTC, Daniel Kozak wrote:
> On Thursday, 11 September 2014 at 14:18:31 UTC, Colin wrote:
>>
>> Ah ok. I get it.
>>
>> Thanks daniel!
>
> a quiet better version:
>
> import std.stdio;
> import std.algorithm;
>
> struct Thing {
> uint x;
> alias x this;
> }
>
> void main(){
> uint[] ar1 = [1, 2, 3, 4, 5];
> auto min1 = ar1.reduce!((a,b) => min(a,b));
> writefln("%s", min1);
>
> Thing[] ar2 = [Thing(1), Thing(2), Thing(4)];
> auto min2 = ar2.reduce!((a,b) => min(a,b));
> writefln("%s", min2);
> }
s/quiet/quite/
|
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | Daniel Kozak: You can just use min: import std.stdio, std.algorithm; struct Thing { uint x; alias x this; } alias minimum = reduce!min; void main() { immutable ar1 = [10, 20, 30, 40, 50]; ar1.minimum.writeln; immutable ar2 = [Thing(10), Thing(20), Thing(40)]; ar2.minimum.writeln; } Bye, bearophile |
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | V Thu, 11 Sep 2014 14:49:02 +0000 bearophile via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> napsáno: > Daniel Kozak: > > You can just use min: > > import std.stdio, std.algorithm; > > struct Thing { > uint x; > alias x this; > } > > alias minimum = reduce!min; > > void main() { > immutable ar1 = [10, 20, 30, 40, 50]; > ar1.minimum.writeln; > > immutable ar2 = [Thing(10), Thing(20), Thing(40)]; > ar2.minimum.writeln; > } > > Bye, > bearophile Yep, this look the most idiomatic :). Why there is no phobos function for minimum of array(range)? |
September 11, 2014 Re: std.algorithm.reduce on an array of structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | On Thursday, 11 September 2014 at 14:56:00 UTC, Daniel Kozak via Digitalmars-d-learn wrote:
> V Thu, 11 Sep 2014 14:49:02 +0000
> bearophile via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> napsáno:
>
>> Daniel Kozak:
>>
>> You can just use min:
>>
>> import std.stdio, std.algorithm;
>>
>> struct Thing {
>> uint x;
>> alias x this;
>> }
>>
>> alias minimum = reduce!min;
>>
>> void main() {
>> immutable ar1 = [10, 20, 30, 40, 50];
>> ar1.minimum.writeln;
>>
>> immutable ar2 = [Thing(10), Thing(20), Thing(40)];
>> ar2.minimum.writeln;
>> }
>>
>> Bye,
>> bearophile
>
> Yep, this look the most idiomatic :).
>
> Why there is no phobos function for minimum of array(range)?
or use alias minimum = reduce!"a < b";
;)
|
Copyright © 1999-2021 by the D Language Foundation