Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

printing elements in list using stream

Tags:

scala

Why does the following code prints only 1 and not the rest of the list elements?

scala> val l: List [Int] = List(1,2,3)
l: List[Int] = List(1, 2, 3)



scala> l.toStream.map(x => print(x))
1res3: scala.collection.immutable.Stream[Unit] = Stream((), ?)

What is the correct way to write this code?

like image 603
user2715182 Avatar asked Jan 20 '18 19:01

user2715182


3 Answers

I'll divide my answer to two:

1. The map method in Scala:

you're using map, which expects a function with no side-effects (printing is a side effect). What you're looking for is:

l.toStream.foreach(x => print(x))

Basically, the general idea is that map takes something and converts it to something else (for example, increasing its value). while foreach is performing some action on that value that isn't supposed to have a return value.

scala> l.toStream.foreach(x => print(x))
123

2. Stream in Scala:

Streams are lazy, so Scala only computes the values it needs. Try this:

scala> l.toStream.map(x => x+1)
res2: scala.collection.immutable.Stream[Int] = Stream(2, ?)

You can see it computed the first value, and the question marks states that it has no idea what comes after it, because it didn't compute it yet. In you're example the first value is nothing, as the print returns no value.

like image 182
shakedzy Avatar answered Oct 12 '22 23:10

shakedzy


Stream is on demand data structure which means not all the values will be evaluated until you need them.

example,

scala> val stream = (1 to 10000).toStream
stream: scala.collection.immutable.Stream[Int] = Stream(1, ?)

Now if you access head and tail, stream will be evaluated upto 2nd index.

scala> stream.head
res13: Int = 1

scala> stream.tail
res14: scala.collection.immutable.Stream[Int] = Stream(2, ?)

scala> stream
res15: scala.collection.immutable.Stream[Int] = Stream(1, 2, ?)

If you access index 99,

scala> stream(99)
res16: Int = 100

Now if you print stream, stream will be evaluated upto 99th index,

scala> stream
res17: scala.collection.immutable.Stream[Int] = Stream(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, ?)

It's always good to process only those in stream, which you need. you can use take() for that.

scala> stream.take(50).foreach(x => print(x + " "))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 

So, answer to your question can be,

scala> List(1,2,3).toStream.take(3).foreach(x => print(x + " "))
1 2 3 

Reference

https://www.coursera.org/learn/progfun2/home/week/2

like image 34
prayagupa Avatar answered Oct 13 '22 01:10

prayagupa


to print complete stream use

l.toStream.print

Output: 1, 2, 3, empty

to print first n values, you may use take(n)

l.toStream.take(2).print

prints output: 1, 2, empty

like image 1
Anurag Sharma Avatar answered Oct 13 '22 00:10

Anurag Sharma