In Scala, what does "view" do?

Viewed 13064

Specifically I'm looking at Problem 1 here

http://pavelfatin.com/scala-for-project-euler/

The code as listed is as follows

val r = (1 until 1000).view.filter(n => n % 3 == 0 || n % 5 == 0).sum

I can follow everything except for "view". In fact if I take out view the code still compiles and produces exactly the same answer.

3 Answers

The following answer is taken from the Views section in the Hands-on Scala book.

When you chain multiple transformations on a collection, we are creating many intermediate collections that are immediately thrown away. For example, in the following code:

@ val myArray = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
@ val myNewArray = myArray.map(x => x + 1).filter(x => x % 2 == 0).slice(1, 3)

myNewArray: Array[Int] = Array(4, 6)

The chain of .map .filter .slice operations ends up traversing the collection three times, creating three new collections, but only the last collection ends up being stored in myNewArray and the others are discarded.

myArray
1,2,3,4,5,6,7,8,9

map(x => x + 1)
2,3,4,5,6,7,8,9,10

filter(x => x % 2 == 0)
2,4,6,8,10

slice(1, 3)
myNewArray
4,6

This creation and traversal of intermediate collections is wasteful. In cases where you have long chains of collection transformations that are becoming a performance bottleneck, you can use the .view method together with .to to fuse the operations together:

@ val myNewArray = myArray.view.map(_ + 1).filter(_ % 2 == 0).slice(1, 3).to(Array)
myNewArray: Array[Int] = Array(4, 6)

Using .view before the map/filter/slice transformation operations defers the actual traversal and creation of a new collection until later, when we call .to to convert it back into a concrete collection type:

myArray
1,2,3,4,5,6,7,8,9

view map filter slice to

myNewArray
4,6

This allows us to perform this chain of map/filter/slice transformations with only a single traversal, and only creating a single output collection. This reduces the amount of unnecessary processing and memory allocations.

Related