Re: Scala beginner question

Kevin Wright <[email protected]> Wed, 2 Mar 2016 21:39:20 +0000
Newsgroups gmane.comp.lang.scala
Message-ID <CABHxxC0XrmZtQN6WdBnVnW=je0g9qB3Gb-yhPCiTHczNewnyhQ@mail.gmail.com>
Numerous better ideas…

1. You’re making checks against two different regexes that can be combined
into one.
2. You’re attempting to match “.” in one of those expressions.  This will
match any character unless you escape it to a literal with “\.”
3. Anything used in a pattern match should begin with an uppercase letter

*Taking points 1,2,3 into consideration:*

val UnwantedChar = """[0-9]|\.|;|,|"|:""".r

4. You don’t need to supply the empty parameter block when calling
`toLowerCase`.  By convention, this syntax is only used for methods with
side effects, not for simple getters or conversions
5. You’re explicitly converting a String to a StringOps - This is already
done for you via the magic of implicits
6. When pattern matching against a regex, it destructures the string
according to any capture groups you’ve defined “(…)” in the regex. You
haven’t specified any, so the “(_*)”s in your matches are useless
7. A succession of case statements wrapped in braces defines a
`PartialFunction` (which is a subclass of `Function`); so you don’t need to
write “(c) => c match”

This gives:

private def transformContent(content: String): String = {
  content.toLowerCase filter {
    case UnwantedChar => false
    case _            => true
  }
}

8. Using filter here is inefficient.  Regexes already have a method for
locating and replacing all matches in a string

private def transformContent(content: String): String =
  UnwantedChar.replaceAllIn(content.toLowerCase, "")


9. Iterators are a good way to deal with lazy and potentially infinite
lists.  `takeWhile` can then be used to catch the terminal null condition.

import scala.io.StdIn
val inputLines = Iterator continually StdIn.readLine() takeWhile (_ != null)
// note the () … because readLine() *is* side-effecting
for(line <- inputLines) {
  …
}

10. The `transformContent` method is now so short that it’s easier to write
the content inline
11. Try to avoid side-effects in the middle of other blocks of code,
they’re better at the boundary of your app

Putting it all together:

import scala.io.StdIn
val UnwantedChar = """[0-9]|\.|;|,|"|:""".r
val inputLines = Iterator continually StdIn.readLine() takeWhile (_ != null)
val filteredInputLines = inputLines map {line =>
  UnwantedChar.replaceAllIn(line.toLowerCase, "")
}
filteredInputLines foreach println


On 2 March 2016 at 16:39, Pietro <[email protected]> wrote:

> Hi everybody,
>
> I am not even sure this is the right place to ask this beginner
> questions nevertheless I do prefer gmane.* to StackOverflow and I wanted
> to give to it a try; feel free to point me to the right newsgroup if
> this isn't the most proper place.
>
> I have recently started to write a simple project in Scala, I got stuck
> in solving a couple of reasonalble simple problems; as many others I am
> from a imperative Java/C background and I am striving to change mindset.
>
> The following function should wipe out all the digits and punctuation
> characters present in the given string "content", anyway the match
> statement never matches where I expect and the string does not get
> modified.
>
> Is there a big mistake I haven't noticed ?
>
>   val digitRE       = """[0-9]""".r
>   val punctuationRE = """.|;|,|"|:""".r
>
>   private def transformContent(content : String) : String = {
>     val _ret = new StringOps(content)
>     _ret.toLowerCase().filter(
>       (c) => {
>         c match {
>           case digitRE(_*)       => false
>           case punctuationRE(_*) => false
>           case _                 => true
>         }
>       })
>   }
>
> Then comes my next question, I would like to write a loop which reads
> from the console user's input and stops when the the user enters a null
> value, that is, they presses ENTER without having entered any characters
> before it.
>
> This is one of my several attempt to achieve it, it obviously does
> not work properly.
>
>     while ( (path = readLine()) != null)
>       println(path)
>   }
>
> The only working solution I have got so far is to
> throw an exception, something like :
>
> try {
>     while (true) {
>             if (whatever)
>                      throw AllDone
>     }
>
> }catch (AllDone) {
>       ...
> }
>
> Any better ideas ?
>
>

-- 
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.