It looks as though there is no partition method on an Iterator in scala 2.7.5 (there is in 2.8). I'd like to have a partition without losing the laziness of the Iterator, so the following is not an option:
itr.toList.partition( someTest(_) )
Can anyone recommend a way of doing this without implementing my own partition method? For example, is there some way of converting an Iterator into a lazily-evaluated Stream?
Have you tried the Stream.fromIterator method? It produces a stream containing the elements of the given iterator :).
An example would be:
val iter = List(1,2,3,4).elements // just a simple iterator
val str = Stream.fromIterator(iter)
str.partition(_ >= 3)
Hope it helps (and it is the thing you had in mind).
EDIT: Just an example to show that this is lazy (and memoised - as all Streams are).
scala> val iter = new Iterator[Int] {
| var lst = List(1,2,3,4)
| def hasNext() = !lst.isEmpty
| def next() = { val x = lst.head; println(x); lst = lst.tail; x }
| }
scala> val stream = Stream.fromIterator(iter)
1
stream: Stream[Int] = Stream(1, ?)
scala> stream.partition(_ >= 2)
2
3
4
res1: (Iterable[Int], Iterable[Int]) = (ArrayBuffer(2, 3, 4),ArrayBuffer(1))
scala> stream.partition(_ >= 3)
res2: (Iterable[Int], Iterable[Int]) = (ArrayBuffer(3, 4),ArrayBuffer(1, 2))
NB: left some output out as it was quite verbose.
-- Flaviu Cipcigan
Related
I have a list:
val k = List(1,2,3,4,-69,78)
and would like to remove all negative elements in the list
I have the following code:
val k = List(1,2,3,4,-69,78)
val a = List()
for( k <- k){
if(k > 0){
a=a:+k
}
}
println(a)
What it is supposed to run through the list and if an element in the list is positive, it should append it to another list in this case list a
however I get the following error:
ScalaFiddle.scala:9: error: reassignment to val
a=a:+k
^
how can I fix this
Please note that I intentionally do not want to use l.filter.
If anyone has a better Idea as to how I can do this, it would be greatly appreciated
Thanks in advance
You are doing in a Java way.
In Scala you should avoid mutable variables and use immutable variables as much as possible.
A better "Scala" solution for your problem is to do the following:
val k = List(1,2,3,4,-69,78)
val a = k.filter(_ > 0)
If you still want to append to the list, you need to change a to be:
val a = new mutable.MutableList[Int]()
And append like this:
a += k
You are trying to reassign a value to a constant (i.e val) which is not possible, the List a needs to be var instead:
val k = List(1,2,3,4,-69,78)
var a = List[Int]()
for(k <- k){
if(k > 0){
a = a :+ k
}
}
println(a)
// Display List(1, 2, 3, 4, 78)
You should use val instead of var.
In short: var can be modified after initialized and val not.
But is important to notice that Scala discourage the use of var because of immutability.
val k = List(1,2,3,4,-69,78)
var a: List[Int] = List()
for( k <- k){
if(k > 0){
a=a:+k
}
}
println(a)
val in scala cannot be reassigned.
When you write val a = List(), you are getting a which holds empty list.
When you write a :+ k you get new list, and you have to assign it to another value in order to access it in future, problem is that you cant reassign a cause it is val.
You could use var but this way is considered as a bad practice.
Another solution is to use functions:
def onlyPositives(k: List[Int], a: List[Int] = List.empty[Int]): List[Int] = k match {
// case when there is no elements left in k
case Nil => a
// we get first element of k and
// if it is positive, append it to a
case x::tail => onlyPositives(tail, if (x > 0) a:+x else a)
}
Now you can write:
val k = List(1, 2, 3, 4, -69, 78)
val a = onlyPositives(k) // List(1, 2, 3, 4, 78)
P. S.
I wonder why you do not use the filter?
I am taking the Functional Programming in Scala course on Coursera and I am having a hard time understanding this code snippet -
def sqrtStream(x: Double): Stream[Double] = {
def improve(guess: Double): Double = (guess+ x/ guess) / 2
lazy val guesses: Stream[Double] = 1 #:: (guesses map improve)
guesses
}
This method would find 10 approximate square root of 4 in increasing order of accuracy when I would do sqrtSteam(4).take(10).toList.
Can someone explain the evaluation strategy of guesses here? My doubt is what value of guesses in substituted when the second value of guesses is picked up?
Let's start from simplified example:
scala> lazy val a: Int = a + 5
a: Int = <lazy>
scala> a
stack overflow here, because of infinite recursion
So a is recalculating til it gets some stable value, like here:
scala> def f(f:() => Any) = 0 //takes function with captured a - returns constant 0
f: (f: () => Any)Int
scala> lazy val a: Int = f(() => a) + 5
a: Int = <lazy>
scala> a
res4: Int = 5 // 0 + 5
You may replace def f(f:() => Any) = 0 with def f(f: => Any) = 0, so a definition will look like it's really passed to the f: lazy val a: Int = f(a) + 5.
Streams use same mechanism - guesses map improve will be passed as parameter called by name (and lambda linked to the lazy a will be saved inside Stream, but not calculated until tail is requested), so it's like lazy val guesses = #::(1, () => guesses map improve). When you call guessess.head - tail will not be evaluated; guesses.tail will lazily return Stream (improve(1), ?), guesses.tail.tail will be Stream(improve(improve(1)), ?) and so on.
The value of guesses is not substituted. A stream is like a list, but its elements are evaluated only when they are needed and then they stored, so next time you access them the evaluation will not be necessary. The reference to the stream itself does not change.
On top of the example Αλεχει wrote, there is a nice explanation in Scala API:
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream
You can easily find out what's going on by modifying the map function, as described in the scaladoc example:
scala> def sqrtStream(x: Double): Stream[Double] = {
| def improve(guess: Double): Double = (guess + x / guess) / 2
| lazy val guesses: Stream[Double] = 1 #:: (guesses map {n =>
| println(n, improve(n))
| improve(n)
| })
| guesses
| }
sqrtStream: (x: Double)Stream[Double]
The output is:
scala> sqrtStream(4).take(10).toList
(1.0,2.5)
(2.5,2.05)
(2.05,2.000609756097561)
(2.000609756097561,2.0000000929222947)
(2.0000000929222947,2.000000000000002)
(2.000000000000002,2.0)
(2.0,2.0)
(2.0,2.0)
(2.0,2.0)
res0: List[Double] = List(1.0, 2.5, 2.05, 2.000609756097561, 2.0000000929222947, 2.000000000000002, 2.0, 2.0, 2.0, 2.0)
I wanted to write it functionally, and the best I could do was:
list.zipWithIndex.filter((tt:Tuple2[Thing,Int])=>(tt._2%3==0)).unzip._1
to get elements 0, 3, 6,...
Is there a more readable Scala idiom for this?
If efficiency is not an issue, you could do the following:
list.grouped(3).map(_.head)
Note that this constructs intermediate lists.
Alternatively you can use a for-comprehension:
for {
(x,i) <- list zipWithIndex
if i % 3 == 0
} yield x
This is of course almost identical to your original solution, just written differently.
My last alternative for you is the use of collect on the zipped list:
list.zipWithIndex.collect {
case (x,i) if i % 3 == 0 => x
}
Not much clear, but still:
xs.indices.collect { case i if i % 3 == 0 => xs(i) }
A nice, functional solution, without creating temporary vectors, lists, and so on:
def everyNth[T](xs: List[T], n:Int): List[T] = xs match {
case hd::tl => hd::everyNth(tl.drop(n-1), n)
case Nil => Nil
}
Clojure has a take-nth function that does what you want, but I was surprised to find that there's not an equivalent method in Scala. You could code up a similar recursive solution based off the Clojure code, or you could read this blog post:
Scala collections: Filtering each n-th element
The author actually has a nice graph at the end showing the relative performance of each of his solutions.
I would do it like in Octave mathematical program.
val indices = 0 until n by 3 // Range 0,3,6,9 ...
and then I needed some way to select the indices from a collection. Obviously I had to have a collection with random-access O(1). Like Array or Vector. For example here I use Vector. To wrap the access into a nice DSL I'd add an implicit class:
implicit class VectorEnrichedWithIndices[T](v:Vector[T]) {
def apply(indices:TraversableOnce[Int]):Vector[T] = {
// some implementation
indices.toVector.map(v)
}
}
The usage would look like:
val vector = list.toVector
val every3rdElement = vector(0 until vector.size by 3)
Ah, how about this?
val l = List(10,9,8,7,6,5,4,3,2,1,0)
for (i <- (0 to l.size - 1 by 3).toList) yield l(i)
//res0: List[Int] = List(10, 7, 4, 1)
which can be made more general by
def seqByN[A](xs: Seq[A], n: Int): Seq[A] = for (i <- 0 to xs.size - 1 by n) yield xs(i)
scala> seqByN(List(10,9,8,7,6,5,4,3,2,1,0), 3)
res1: Seq[Int] = Vector(10,7,4,1)
scala> seqByN(List(10,9,8,7,6,5,4,3,2,1,0), 3).toList
res2: Seq[Int] = List(10,7,4,1)
scala> seqByN(List[Int](), 3)
res1: Seq[Int] = Vector()
But by functional do you mean only using the various List combinator functions? Otherwise, are Streams functional enough?
def fromByN[A](xs: List[A], n: Int): Stream[A] = if (xs.isEmpty) Stream.empty else
xs.head #:: fromByN(xs drop n, n)
scala> fromByN(List(10,9,8,7,6,5,4,3,2,1,0), 3).toList
res17: List[Int] = List(10, 7, 4, 1)
I am new to Scala and functional programming.
I was solving problem where you have to read number, and then that number of integers. After that you should calculate sum of all digits in all the integers.
Here is my code
def sumDigits(line: String) =
line.foldLeft(0)(_ + _.toInt - '0'.toInt)
def main(args: Array[String]) {
val numberOfLines = Console.readInt
val lines = for (i <- 1 to numberOfLines) yield Console.readLine
println(lines.foldLeft(0)( _ + sumDigits(_)))
}
Is there more elegant or efficient way?
sumDigits() can be implemented easier with sum:
def sumDigits(line: String) = line.map(_.asDigit).sum
Second foldLeft() can also be replaced with sum:
lines.map(sumDigits).sum
Which brings us to the final version (notice there is no main, instead with extend App):
object Main extends App {
def sumDigits(line: String) = line.map(_.asDigit).sum
val lines = for (_ <- 1 to Console.readInt) yield Console.readLine
println(lines.map(sumDigits).sum)
}
Or if you really want to squeeze as much as possible in one line, inline sumDigits (not recommended):
lines.map(_.map(_.asDigit).sum).sum
I like compact code, so I might (if I was really going for brevity)
object Reads extends App {
import Console._
println( Seq.fill(readInt){readLine.map(_ - '0').sum}.sum )
}
which sets the number of lines inline and does the processing as you go. No error checking, though. You could throw in a .filter(_.isDigit) right after the readLine to at least discard non-digits. You might also def p[A](a: A) = { println(a); a } and wrap the reads in p so you can see what had been typed (by default on some platforms at least there's no echo to screen).
One-liner Answer:
Iterator.continually(Console.readLine).take(Console.readInt).toList.flatten.map(_.asDigit).sum
To start with, you have to do some kind of parsing on line to break apart the existing decimal integers sub-strings:
val numbers = "5 1 4 9 16 25"
val ints = numbers.split("\\s+").toList.map(_.toInt)
Then you want to pull off the first one as the count and keep the rest to decode and sum:
val count :: numbers = ints
Then use the built-in sum method:
val sum = numbers.sum
Altogether in the REPL:
scala> val numbers = "5 1 4 9 16 25"
numbers: String = 5 1 4 9 16 25
scala> val ints = numbers.split("\\s+").toList.map(_.toInt)
ints: List[Int] = List(5, 1, 4, 9, 16, 25)
scala> val count :: numbers = ints
count: Int = 5
numbers: List[Int] = List(1, 4, 9, 16, 25)
scala> val sum = numbers.sum
sum: Int = 55
If you want to do something with the leading number count, you could verify that it's correct:
scala> assert(count == numbers.length)
Which produces no output, since the assertion passes.
Can someone please explain the following output from the REPL?
I'm defining 2 (infinite) Streams that are otherwise identical in their definition except that map is preceded by . (period) in one definition and a _ _ (space) in the other.
I can see that this would cause map to bind differently, but what happens to the 1 in the output from the second definition?
Thanks.
scala> lazy val infinite: Stream[Int] = 1 #:: infinite.map(_+1)
infinite: Stream[Int] = <lazy>
scala> val l = infinite.take(10).toList.mkString(",")
l: String = 1,2,3,4,5,6,7,8,9,10
scala> lazy val infinite2: Stream[Int] = 1 #:: infinite2 map(_+1)
infinite2: Stream[Int] = <lazy>
scala> val l2 = infinite2.take(10).toList.mkString(",")
l2: String = 2,3,4,5,6,7,8,9,10,11
It's about method associativity. This:
1 #:: infinite.map(_+1)
is quite straightforward while this:
1 #:: infinite2 map(_+1)
is interpreted by the compiler as:
(1 #:: infinite2) map(_+1)
1 #:: infinite2 is your desired stream, but before you return it, you apply lazy transformation adding one to every item. This explains why 1 never appears as a result - after transformation it becomes 2.
For more details see: Operator precedence in Scala. Since # is not a special character, it is treated equally with map, thus methods are evaluated from left to right.
In the infinite2 case, what you've expressed is equivalent to the following:
lazy val infinite2: Stream[Int] = (1 #:: infinite2) map(_ + 1)
Since the stream starts with 1, the map will add 1 to the first element.