One very convenient way to do this is with the zipped
method on tuples. Put two collections in, get out two arguments to a function!
(ar1,ar2).zipped.foreach((x,y) => println(x+y))
This is both convenient to write and fast, since you don't need to build a tuple to store each pair (as you would with (ar1 zip ar2)
) which you then have to take apart again. Both forms of zip stop when the shorter of the two collections is exhausted.
If you have something more complicated (e.g. you need to do math on the index), the canonical solution is to zip in the index:
ar1.zipWithIndex.foreach{ case(x,i) => println(x+ar2(i)) }
The method you are using is more rapidly and compactly done as follows, an can be useful:
ar1.indices.foreach(i => println(ar1(i)+ar2(i)))
although this only works if the first collection is no longer than the second. You can also specify your ranges explcitly:
(0 until (ar1.size min ar2.size)).foreach(i => println(ar1(i)+ar2(i)))
to get around this problem. (You can see why zip
and zipped
are preferred unless what you're doing is too complicated for this to work easily.)
If it is not a parallel collection (and usually it is not unless you call .par
), it's also possible, though not recommended, to keep track with a mutable variable:
{ var i=-1; ar1.foreach{ x => i += 1; println(x+ar2(i)) } }
There are a very limited number of cases where this is necessary (e.g. if you may want to skip or backtrack on some of the other collection(s)); if you can avoid having to do this, you'll usually end up with code that's easier to reason about.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…