2

Can I get this type of do-loop in Mathematica?

Do[Print[j," ",k," ",l], {j,k,l, {a, b,z}, { c, d,y} }]

I want this to work so that, in the first iteration, j, k and l take on the values {a, b, z} and then, in the second iteration, the values {c, d, y}.

So the result should be

a b z
c d y

I'm interested in any kind of a looping structure which can do this job for me. I don't necessarily need a do-loop.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
user22180
  • 295
  • 1
  • 3
  • 10
  • As I mentioned at the last I want a loop , as printing is not my goal. I have to evaluate some expression there instead of Printing. Thanks – user22180 May 13 '14 at 21:27
  • @Kuba, Hello I need the second one, that is one loop over sets of three arguments choosing from an array of order n * 3. – user22180 May 13 '14 at 21:49
  • @Kuba,thanks for the help. Now I can do what I wanted.f[x1_, x2_, x3_, x4_] := x1 + x2 + x3 + x4;
    f[#1, x2, #2, #3] &[a, b, z] ;
    Do[Print[f[#1, #2, #3, x4] &[i[[1]], i[[2]], i[[3]]]], {i, {{a, b, z}, {c, d, y}}}];. I have used [i[[1]], i[[2]], i[[3]]]]. Please tell me whether there is any equivalent easy way of writing this. thanks
    – user22180 May 13 '14 at 22:28

2 Answers2

4

In Mathematica, we are far more likely to map functions over lists in various ways than to use looping constructs. Since the functions that are mapped are often very specialized and not for general use, they are -- more often than not -- defined as pure functions.

Here are two non-looping iterators that can do what you ask. They will work on lists of triplets on any length, and the length does not have to be known. The first method preserves some semblance to your formuation of the problem.

data = {{a, b, z}, {c, d, y}};
Print[#1, " ", #2, " ", #3] & @@@ data;
a b z

c d y

This second method adheres closer to normal Mathematica functional programming style.

Row[#, " "] & /@ data // Column
a b z
c d y

In both cases the results are purely for display. Note that first method produces a new cell for each sub-list, while the second always produces a single cell.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
1

While m_goldberg is entirely correct that there are more idiomatic approaches within Mathematica I would like to answer the question that was asked. Yes, you can get that kind of iteration. You need to be familiar with the different scoping constructs in Mathematica to understand one of the choices that you face. Do and Table operate by the mechanism of Block in that they temporarily change the value of their iterators. So for example:

foo := bar

Do[Print[foo], {bar, 1, 3}]    (* outputs 1, 2, 3 *)

In many cases, such as your example, you do not need that behavior; it is sufficient to replace literal appearances of the iterator variables in the body of the loop. This is akin to With or ReplaceAll. If so we can use destructuring to assign values to the variables:

Do[
  iter /. {j_, k_, l_} :> Print[j, " ", k, " ", l],
  {iter, {{a, b, z}, {c, d, y}}}
]

If you do need the full Block-like scoping then you need something more. I will use Block to prevent external modification of the working variables. Using a different form of destructuring the assignment {j, k, l} = iter is made as the first operation in the body of the loop, separated by CompoundExpression.

foo := Sequence[j, " ", k, " ", l];

Block[{j, k, l},
  Do[
    {j, k, l} = iter; Print[foo],
    {iter, {{a, b, z}, {c, d, y}}}
  ]
]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371