10.11. Using zipWithIndex or zip to Create Loop Counters
Problem
You want to loop over a sequential collection, and you’d like to have access to a counter in the loop, without having to manually create a counter.
Solution
Use the zipWithIndex
or
zip
methods to create a counter
automatically. Assuming you have a sequential collection of days:
val
days
=
Array
(
"Sunday"
,
"Monday"
,
"Tuesday"
,
"Wednesday"
,
"Thursday"
,
"Friday"
,
"Saturday"
)
you can print the elements in the collection with a counter using
the zipWithIndex
and foreach
methods:
days
.
zipWithIndex
.
foreach
{
case
(
day
,
count
)
=>
println
(
s
"$count is $day"
)
}
As you’ll see in the Discussion, this works because zipWithIndex
returns a series of Tuple2
elements in an Array
, like this:
Array((Sunday,0), (Monday,1), ...
and the case
statement in the
foreach
loop matches a
Tuple2
.
You can also use zipWithIndex
with a for
loop:
for
((
day
,
count
)
<-
days
.
zipWithIndex
)
{
println
(
s
"$count is $day"
)
}
Both loops result in the following output:
0 is Sunday 1 is Monday 2 is Tuesday 3 is Wednesday 4 is Thursday 5 is Friday 6 is Saturday
When using zipWithIndex
, the
counter always starts at 0
. You can
also use the zip
method with a
Stream
to create a counter. This
gives you a way to control the starting value:
scala>for ((day,count) <- days.zip(Stream from 1)) {
|println(s"day $count is $day")
|}
Discussion
When zipWithIndex
is used on a
sequence, it returns a sequence of Tuple2
elements, as shown in this
example:
scala> val list = List("a", "b", "c")
list: ...
Get Scala Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.