# Using Map with If

I have an If statement I need to carry out where the result should be a single number for each time the if is executed. What I have at the moment returns a list for each time the If is executed. I specifically do not want to use a Do loop so is there a way to use Map to do this?

x = {0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915};
y = {0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915, 0.897409001634915,
0.897409001634915, 0.897409001634915};
z = {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

TimeModelSelection[41]
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}


The first few lines of the result are

Map[If[# == 0, x*y, z] &, TimeModelSelection[41], {1}]
{{0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162}, {0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162, 0.8053429162, 0.8053429162, 0.8053429162,
0.8053429162},...


I have also tried thefollowing without luck

Map[If[# == 0, x[[#]]*y[[#]], z[[#]]] &, TimeModelSelection[41], {1}]

-

If I understand the statement, you wish to do this:

Table[If[time[[i]] == 0, x[[i]] y[[i]], z[[i]]], {i, 1, Length[time]}]


but you wish to do it without Table or Do. One way to accomplish this is quite straightforward:

(1 - time) x y + time z


which gives the same result as above, though this assumes that the time variable is either zero (when you wish to have x*y) or one (when you wish to use z). This uses time as shorthand for your variable TimeModelSelection[41].

Another, more "functional programming" way to approach this is to define the basic operation as a function:

f[{t_, x_, y_, z_}] := If[t == 0, x y, z]


and then call the function using Map

Map[f, # &, {1}] /@ Transpose[{time, x, y, z}]


which again gives the same answer. Finally, for the purists, you can do the same thing without defining any auxiliary function (like f) by using pure functions

Apply[If, {#[[1]] == 0, #[[2]] #[[3]], #[[4]]} &, {1}] /@ Transpose[{time, x, y, z}]


though it is probably hard to read. Mr. Wizard's use of MapThread is probably a better and more readable way to get a purely functional form than this use of Apply.

-
The (1-time)xy... answer is great. It's exactly what I needed, thanks. –  Lara Jordan Jun 3 '13 at 8:59

bill already showed how to do this very efficiently with a numeric approach, but a bit closer to what you attempted and your direct request is MapThread:

SeedRandom[1]
time = RandomInteger[1, 20]

MapThread[If[# == 0, #2*#3, #4] &, {time, x, y, z}]

{0, 0, 0.805343, 0, 0.805343, 0.805343, 0.805343, 0, 0.805343, 1, 0.805343, 0.805343,
0.805343, 0.805343, 0.805343, 0.805343, 0.805343, 0, 0, 0}

-
If the OP wants named variables instead of slots, then this can be done: MapThread[Function[{t, x, y, z}, If[t == 0, x y, z]], {time, x, y, z}]. –  Guess who it is. Jun 3 '13 at 12:30