www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - range foreach lambda

reply "ddos" <oggs gmx.at> writes:
for example i have an array

int[] a = [1,2,3,4,5];

and a function

auto twice  = function (int x) => x * 2;

how can i apply the function to each element in a without using a 
forloop? - is there a function to do this?

a.foreach(x => x * 2);
a == [2,4,6,8,10]
Jul 17 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
ddos:

 auto twice  = function (int x) => x * 2;
"function" is not necessary. And generally it's better to assign to immutables, unless you need to mutate the variable "twice" later.
 how can i apply the function to each element in a without using 
 a forloop? - is there a function to do this?
Generally such range based functions are designed for a functional style of coding, so a map is meant to produce a new (lazy) range. If you really want to mutate in-place, you can use a copy: void main() { import std.algorithm; auto a = [1, 2, 3, 4, 5]; immutable twice = (int x) => x * 2; a.map!(x => x * 2).copy(a); assert(a == [2, 4, 6, 8, 10]); } But this could introduce bugs, so better to limit the number of times you use similar code. So this is more idiomatic and safer: void main() { import std.algorithm; immutable data = [1, 2, 3, 4, 5]; auto result = data.map!(x => x * 2); assert(result.equal([2, 4, 6, 8, 10])); } Bye, bearophile
Jul 17 2014
parent reply "ddos" <oggs gmx.at> writes:
thx alot! its not important to me that the function is not 
evaluated in place
since you gave me such a straight answer i'd like to bother you 
with another question :)

for example i have now two ranges:

immutable a = [1,2,3,4];
immutable b = [2,3,4,5];

how do i add the elements in a and b elementwise in a functional 
style?

a+b == [3,5,7,9]

usually i'd do something like this:

int[4] o;
for(int i=0;i<4;i++)
{
   o[i] = a[i] + b[i];
}
Jul 17 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
ddos:

 how do i add the elements in a and b elementwise
Several ways to do it: void main() { import std.range, std.algorithm, std.array; immutable a = [1, 2, 3, 4]; immutable b = [2, 3, 4, 5]; int[] c1; c1.reserve(a.length); // Optional. foreach (immutable x, immutable y; a.zip(b)) c1 ~= x + y; assert(c1 == [3, 5, 7, 9]); auto c2a = a.zip(b).map!(ab => ab[0] + ab[1]); // Lazy. assert(c2a.equal([3, 5, 7, 9])); const c2b = c2a.array; assert(c2b == [3, 5, 7, 9]); auto c3 = new int[a.length]; c3[] = a[] + b[]; assert(c3 == [3, 5, 7, 9]); int[4] c4 = a[] + b[]; assert(c4 == [3, 5, 7, 9]); } Bye, bearophile
Jul 17 2014