std.algorithm each documentation terse

John Colvin via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jul 20 07:59:19 PDT 2015


On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote:
> I have found the documentation for each in std.algorithm a bit 
> terse. It seemed like it was an eager version of map, but it 
> seems to be a bit more limited than that.
>
> In particular, the documentation says that if you can mutate 
> the value in place, then you can call each on it. The first 
> thing I noticed is that this works easiest (beyond in place 
> operators) when you're using a void function and taking the 
> input you want to change as ref. This is what I did in the foo 
> and bar functions below. However, it's not the same thing as 
> just applying the function. In the baz function, I mutate the 
> value and then return a different value. Using baz with each 
> doesn't change the value by 2, only by 1.
>
> What really confused me is that I can't use a lambda with each 
> in a similar way as map. I think this is because the lambdas 
> I'm using really aren't void functions. The part after the => 
> is basically a return statement, so I'm not really mutating 
> anything in place. Is there any way to do this with lambdas or 
> are void functions required?
>
> Is there a way to write a void lambda that would work with each?
>
> import std.range : iota;
> import std.algorithm : each;
> import std.array : array;
>
> void foo(ref int x)
> {
> 	x += 1;
> }
>
> void bar(ref int x)
> {
> 	x *= x;
> }
>
> int baz(ref int x)
> {
> 	x += 1;
> 	return x + 1;
> }
>
> void main()
> {
> 	auto x = iota(3).array;
> 	
> 	x.each!((ref a) => a++);
> 	assert(x == [1, 2, 3]); //What you would expect
> 	
> 	x.each!((ref a) => foo(a));
> 	assert(x == [2, 3, 4]); //What you would expect
> 	
> 	x.each!((ref a) => bar(a));
> 	assert(x == [4, 9, 16]); //What you would expect
> 	
> 	x.each!((ref a) => baz(a));
> 	assert(x == [5, 10, 17]); //What I would expect after thinking 
> about it for a while
> 							
> 	x.each!((ref a) => a + 1);
> 	assert(x == [5, 10, 17]); //Not what I would expect
> 	
> 	x.each!((ref a) => a * a);
> 	assert(x == [5, 10, 17]); //Not what I would expect
> }

Everything is exactly as I would expect. Lambdas with => are just 
shorthand that skips the return expression and std.algorithm.each 
just calls the lambda for each element in x, it doesn't say 
anything about copying the result back in to x.

x.map!(a => a * a).copy(x);


More information about the Digitalmars-d-learn mailing list