scala nested for/yield generator to extract substring - scala

I am new to scala. Pls be gentle. My problem for the moment is the syntax error.
(But my ultimate goal is to print each group of 3 characters from every string in the list...now i am merely printing the first 3 characters of every string)
def do_stuff():Unit = {
val s = List[String]("abc", "fds", "654444654")
for {
i <- s.indices
r <- 0 to s(i).length by 3
println(s(i).substring(0,3))
} yield {s(i)}
}
do_stuff()
i am getting this error. it is syntax related, but i dont undersatnd..
Error:(12, 18) ')' expected but '.' found.
println(s(i).substring(0,3))

That code doesn't compile because in a for-comprehension, you can't just put a print statement, you always need an assignment, in this case, a dummy one can solve your porblem.
_ = println(s(i).substring(0,3))
EDIT
If you want the combination of 3 elements in every String you can use combinations method from collections.
List("abc", "fds", "654444654").flatMap(_.combinations(3).toList)

Related

Scala, user input till only newline is given

I have tried to get multiple user inputs to print them in Scala IDE.
I have tried the this piece of code
println(scala.io.StdIn.readLine())
which works, as the IDE takes my input and then print it in the line but this works only for a single input.
I want the code to take multiple inputs till only newline is entered. example,
1
2
3
so i decided we needed an iterator for the input, which led me to try the following 2 lines of code seperately
var in = Iterator.continually{ scala.io.StdIn.readLine() }.takeWhile { x => x != null}
and
var in = io.Source.stdin.getLines().takeWhile { x => x != null}
Unfortunately none of them worked as the IDE is not taking my input at all.
You're really close.
val in = Iterator.continually(io.StdIn.readLine).takeWhile(_.nonEmpty).toList
This will read input until an empty string is entered and saves the input in a List[String]. The reason for toList is because an Iterator element doesn't become real until next is called on it, so readLine won't be called until the next element is required. The transition to List creates all the elements of the Iterator.
update
As #vossad01 has pointed out, this can be made safer for unexpected input.
val in = Iterator.continually(io.StdIn.readLine)
.takeWhile(Option(_).fold(false)(_.nonEmpty))
.toList

Scala String and Char Types

val args = "To now was far back saw the *$# giant planet itself, het a won"
Find and sort distinct anagram pairs from "args":
now won
was saw
the het
First I clean up the args and put them in an array.
val argsArray = args.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase.split(" ").distinct.sorted
argsArray: Array[String] = Array("", a, back, far, giant, het, itself, now, planet, saw, the, to, was, won)
My idea is to reduce each word to an array of char, then sort, then compare. But I get stuck because the following returns the wrong data type ---- String = [C#2736f24a
for (i <- 0 until argsArray.length - 1){
val j = i + 1
if(argsArray(i).toCharArray.sorted == argsArray(j).toCharArray.sorted) {
println(argsArray(i).toCharArray + " " + argsArray(j).toCharArray)
}
}
I assume there are better ways to solve this, but what I really want to learn is how to deal with this data type problem, so please help me solve that and then I will refactor later. Thank you.
[C#<whatever> is just how Array[Char] is converted to String on JVM. Remove calls to toCharArray from println and it'll print the strings you want. The second error, with the current code in the question, is the equality check: == on arrays checks that they are the same object, and since sorted will always create a new array, the left and right sides are always different objects even if they have the same elements.

What does a pure expression mean in Scala?

I have two questions. The first one: is code a pure expression?
lazy val code: Unit = {
// block of code
var s = "abc"
for (i <- 0 until 10) println(i)
s += s concat "def"
println(s)
}
And the second one: What does a pure expression mean? Is this a some code which does not return anything?
A pure expression is a computation that serves only to produce a resulting value - it has no side effects. In the case of your field code above, you make calls to print stuff to the console (println), which is considered a side effect, so it is not a pure expression. An example of a pure expression would be something like:
lazy val foo = 2 + 3
It does nothing apart from generate the final value for foo, and could safely be replaced by the result of the computation (5) without changing the outcome of the program in any way. If you made such a replacement in your code above:
lazy val code: Unit = ()
you would change the program - it no longer prints anything to the console.
Have a look here, for example, for more information about pure functions and pure expressions, and their significance in functional programming.

The semicolon inference doesn't work when an assignment statement is followed by curly braces in Scala?

At http://www.artima.com/pins1ed/builtin-control-structures.html#7.7,
I see the following code
val a = 1;
{
val a = 2
println(a)
}
println(a)
where it says that the semicolon is required here, but why?
From the rule at http://www.artima.com/pins1ed/classes-and-objects.html#4.2 ,
I think the semicolon should be auto added since
val a = 1 can be a legal statement.
The next line begins with {, which I think can start a legal statement. (Since there's no compile error if I add the semicolon and separate the first two lines into two statements.)
val a = 1 is not in parentheses or brackets.
Because it would be a legal call to apply:
implicit class RichInt(i: Int) {
def apply(thunk: => Unit) = 33
}
val a = 1
{
val a = 2
println(a)
}
println(a) // 33 !
1 { ... } is short for 1.apply {...}. Now apply is not defined for an Int by default, but as the implicit enrichment shows, it is perfectly possible.
Edit: The semicolon inference conditions are described in 'ยง1.2 Newline Characters' of the Scala Language Specification. The inferred semicolon is called 'special token "nl"' in that text.
In general, three rules are given (summarised ex-negativo in this blog entry), and in your example they are all satisfied. The reason that the semicolon is still not inferred is given further down in the text.
The Scala grammar ... contains productions where optional nl tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not [!] terminate an expression or statement.
The relevant case of such an extra rule is the following:
A single new line token is accepted
โ€“ in front of an opening brace โ€œ{โ€, if that brace is a legal continuation of the current statement or expression ...
Example 1.2.2 shows the case of anonymous an subclass which I had referred to in the comment.

Why does Scala's semicolon inference fail here?

On compiling the following code with Scala 2.7.3,
package spoj
object Prime1 {
def main(args: Array[String]) {
def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0))
val read = new java.util.Scanner(System.in)
var nTests = read nextInt // [*]
while(nTests > 0) {
val (start, end) = (read nextInt, read nextInt)
start to end filter(isPrime(_)) foreach println
println
nTests -= 1
}
}
}
I get the following compile time error :
PRIME1.scala:8: error: illegal start of simple expression
while(nTests > 0) {
^
PRIME1.scala:14: error: block must end in result expression, not in definition
}
^
two errors found
When I add a semicolon at the end of the line commented as [*], the program compiles fine. Can anyone please explain why does Scala's semicolon inference fail to work on that particular line?
Is it because scala is assuming that you are using the syntax a foo b (equivalent to a.foo(b)) in your call to readInt. That is, it assumes that the while loop is the argument to readInt (recall that every expression has a type) and hence the last statement is a declaration:
var ntests = read nextInt x
wherex is your while block.
I must say that, as a point of preference, I've now returned to using the usual a.foo(b) syntax over a foo b unless specifically working with a DSL which was designed with that use in mind (like actors' a ! b). It makes things much clearer in general and you don't get bitten by weird stuff like this!
Additional comment to the answer by oxbow_lakes...
var ntests = read nextInt()
Should fix things for you as an alternative to the semicolon
To add a little more about the semicolon inference, Scala actually does this in two stages. First it infers a special token called nl by the language spec. The parser allows nl to be used as a statement separator, as well as semicolons. However, nl is also permitted in a few other places by the grammar. In particular, a single nl is allowed after infix operators when the first token on the next line can start an expression -- and while can start an expression, which is why it interprets it that way. Unfortunately, although while can start a expression, a while statement cannot be used in an infix expression, hence the error. Personally, it seems a rather quirky way for the parser to work, but there's quite plausibly a sane rationale behind it for all I know!
As yet another option to the others suggested, putting a blank newline between your [*] line and the while line will also fix the problem, because only a single nl is permitted after infix operators, so multiple nls forces a different interpretation by the parser.