'00.scala'에 해당되는 글 49건

  1. 2014.04.02 scala api
  2. 2014.03.28 Scala - How to open and read files in Scala
  3. 2014.03.28 How to load an XML URL in Scala (contents of an XML web page)
  4. 2014.03.28 How to load (open and read) an XML file in Scala
  5. 2014.03.28 Scala: Saving/writing XML to a file
  6. 2014.03.28 How to mix Scala and XML to dynamically generate XML
  7. 2014.03.28 A Scala REST client using the Apache HttpClient library
  8. 2014.03.28 A Scala JDBC connection and SQL SELECT example
  9. 2014.03.28 Scala tuple examples and syntax
  10. 2014.03.28 Iterating over Scala Maps (for and foreach loop examples)
  11. 2014.03.28 Scala Maps (Map class examples)
  12. 2014.03.28 Scala List class filter method examples
  13. 2014.03.28 Scala List class examples - range, fill, tabulate, appending, foreach, more ...
  14. 2014.03.28 Five ways to create a Scala List
  15. 2014.03.28 How to merge Scala Lists
  16. 2014.03.28 Iterating over Scala Lists with foreach and for
  17. 2014.03.28 Convert a Scala array to string with mkString
  18. 2014.03.28 Iterating over Scala Maps (for and foreach loop examples)
  19. 2014.03.28 Iterating over Scala Lists with foreach and for
  20. 2014.03.28 How to create and use multi-dimensional arrays (2D, 3D, etc.) in Scala
  21. 2014.03.28 Converting Java collections to Scala collections
  22. 2014.03.28 Scala data types (bit sizes, ranges, and docs)
  23. 2014.03.28 Convert a Scala array to string with mkString
  24. 2014.03.28 Simple Scala string array examples
  25. 2014.03.28 Mutable Scala arrays (adding elements to arrays)
  26. 2014.03.28 Scala - Declaring a null var variable (field) before a try, catch, finally block
  27. 2014.03.28 The Scala try, catch, finally syntax (multiple exceptions, wildcard operator)
  28. 2014.03.28 Scala FAQ - How to create a private default/primary constructor
  29. 2014.03.28 Scala - How to rename a class when you import it (a 'rename on import' syntax example)
  30. 2014.03.28 Scala equivalent of Java .class (classOf)
00.scala2014. 4. 2. 00:58
반응형

http://www.scala-lang.org/api/current/#package

http://www.slideshare.net/choijeongyeol/scala-for-play

scala cheatsheets

http://docs.scala-lang.org/cheatsheets/


스칼라를 배울 수 있는 사이트

스칼라 서적(영문)

  • Programming in Scala : 마틴 오더스키가 참여한 스칼라 서적. 강추!!, Scala 2.8 기준.
  • Programming Scala : 오렐리에서 나옴. 읽어본 사람 없어서 내용은 잘 모름.
  • Programming Scala : Pragmatic에서 나온 스칼라 서적. 읽어볼만은 하지만 빠진 내용이 많아서 많이 추천하지는 않음.
  • Scala in Depth : 매닝에서 나온 서적. 읽어본 사람이 없어서 내용은 잘 모름.

그외 참고 자료

발표자료

슬라이드


Posted by 1010
00.scala2014. 3. 28. 15:38
반응형

Scala file FAQ: How do I open and read files in Scala?

When you're writing Scala scripts, you often want to read text files. Fortunately it's pretty easy to openand read from a file in Scala. You can just use an approach like this:

import scala.io.Source

val filename = "fileopen.scala"
for (line <- Source.fromFile(filename).getLines()) {
  println(line)
}

As you can see, this approach uses the scala.io.Source class. Within the for loop I can now access each line of the file using the 'line' object, and in this case I'm printing each line using println.

A variation of this is to add the mkString function to the file-reading portion of that code, like this:

val fileContents = Source.fromFile(filename).getLines.mkString

Another nice file-reading example comes from Bruce Eckel's website:

val fileLines = io.Source.fromFile("Colors.scala").getLines.toList
fileLines.foreach(println)

As you can see from that example, you can read an entire text file into a Scala List with what appears to be only one line of source code.

Handling file exceptions

Of course you can generate exceptions when trying to open a file, and if you want to handle your exceptions, you use a syntax similar to the Java try/catch syntax, like this:

import scala.io.Source

val filename = "no-such-file.scala"
try {
  for (line <- Source.fromFile(filename).getLines()) {
    println(line)
  }
} catch {
  case ex: Exception => println("Bummer, an exception happened.")
}

If I change that Exception line to print my exception object, like this:

case ex: Exception => println(ex)

and then run this script again, I can see that this code throws a java.io.FileNotFoundException exception when it fails:

java.io.FileNotFoundException: no-such-file.scala (No such file or directory)

As a result, if I want to catch all the old Java exceptions like I used to, I can write a Scala script like this to catch the Java FileNotFoundException and IOException:

import scala.io.Source
import java.io.{FileReader, FileNotFoundException, IOException}

val filename = "no-such-file.scala"
try {
for (line <- Source.fromFile(filename).getLines()) {
  println(line)
}
} catch {
  case ex: FileNotFoundException => println("Couldn't find that file.")
  case ex: IOException => println("Had an IOException trying to read that file")
}


Posted by 1010
00.scala2014. 3. 28. 15:38
반응형

Scala XML FAQ: How do I load an XML URL in Scala? (How do I read/download the contents of an XML URL in Scala?)

To load the contents of an XML URL (web page) in Scala, such as an RSS news feed or RESTful web service, just use the load method of the Scala XML class:

val xml = XML.load("http://www.devdaily.com/rss.xml")

Here's an example of what this looks like in the Scala REPL:

scala> import scala.xml.XML
import scala.xml.XML

scala> val xml = XML.load("http://www.devdaily.com/rss.xml")
xml: scala.xml.Elem = 
<rss xml:base="http://www.devdaily.com" version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>

(output goes on for about ten more lines)

Once you have your XML object (an instance of the scala.xml.Elem class), you can search it as usual. Since my RSS feed includes an "item" tag, I can get the number of item tags in the XML contents:

scala> (xml \\ "item").length
res5: Int = 10

I can also do things like searching for "title" elements, such as getting the text from the first RSS title element:

scala> val firstTitle = (xml \\ "channel" \ "title") text
firstTitle: String = devdaily.com

As you can see, loading the contents of an XML URL in Scala is very easy.

Posted by 1010
00.scala2014. 3. 28. 15:37
반응형

Scala FAQ: How do I load an XML file in Scala? (How do I open and read an XML file in Scala?)

I demonstrated this in my earlier Scala XML - Searching XMLNS namespaces, XPath tutorial, but you can load an XML file in Scala like this:

import scala.xml.XML
val xml = XML.loadFile("/Users/al/Projects/Scala/yahoo-weather.xml")

Once you've loaded the file contents like that, you can manipulate them as desired, such as searching the XML using XPath constructs like this:

val temp = (xml \\ "channel" \\ "item" \ "condition" \ "@temp") text

In summary, if you need to load an XML file in Scala, I hope this has been helpful.

Posted by 1010
00.scala2014. 3. 28. 15:37
반응형

Problem: You want to write XML data to a file in a Scala application, such as saving application data or configuration information to a file.

Solution

Use the scala.xml.XML.save method to write a Scala literal to a file. Given this XML literal:

// create an XML variable
val portfolio = 
  <portfolio>
    <stocks>
      <stock>AAPL</stock>
      <stock>AMZN</stock>
      <stock>GOOG</stock>
    </stocks>
    <reits>
      <reit>Super REIT 1</reit>
    </reits>
  </portfolio>

write the literal to file with the save method:

// save the XML to a file
scala.xml.XML.save("portfolio.xml", portfolio)

This creates a plain-text file named portfolio.xml in the current directory, containing the XML literal shown.

As with any file-writing code, beware that XML.save can throw an exception:

scala> scala.xml.XML.save("/foo/bar/baz", portfolio)
java.io.FileNotFoundException: /foo/bar/baz (No such file or directory)

Additional save parameters

The save method lets you specify other parameters, including the encoding to use, whether or not to write an XML declaration, and whether or not to write a DOCTYPE declaration.

To write the data to a file with encoding information, use this approach:

XML.save("portfolio.xml", portfolio, "UTF-8", true, null)

This results in the following header being added to the file:

<?xml version='1.0' encoding='UTF-8'?>

To add a DOCTYPE to the file, first import the necessary classes:

import scala.xml.dtd.{DocType, PublicID}

Then create a DocType instance, and save the file with that instance:

val doctype = DocType("html",
  PublicID("-//W3C//DTD XHTML 1.0 Strict//EN",
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
  Nil)

XML.save("portfolio.xml", portfolio, "UTF-8", true, doctype)

With this configuration, the following DOCTYPE line is added to the output file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

The scala.xml package also includes a Utility object with a small collection of useful methods that let you sort node attributes, trim elements, remove comments, and more.

Pretty printing

If it’s important that the XML can be easily read by a human being, it’s best to use the PrettyPrinter class to make sure the XML is “human readable.” But because the PrettyPrinter returns a String, you’ll need to write it to a file using another method. I have my own FileUtils class, so the process looks like this:

val portfolio =
  <portfolio>
    <stocks>
      <stock>AAPL</stock><stock>AMZN</stock><stock>GOOG</stock>
    </stocks>
    <reits><reit>Super REIT 1</reit></reits>
  </portfolio>

// 80 characters wide, 2 character indentation
val prettyPrinter = new scala.xml.PrettyPrinter(80, 2)
val prettyXml = prettyPrinter.format(portfolio)
FileUtils.save("portfolio.xml", prettyXml)


Posted by 1010
00.scala2014. 3. 28. 14:23
반응형

Problem: You want to dynamically generate XML from your Scala source code, such as creating output for a SOAP web service.

Solution

A great feature of Scala’s XML support is that you can interweave XML and regular Scala source code together. This lets you dynamically generate XML from your Scala code.

To create XML with dynamic, embedded data, just put your Scala code in curly braces inside the XML tags, as shown in the following example:

scala> val name = "Bill"
name: String = Bill

scala> val age = 42
age: Int = 42

scala> val p = <person><name>{name}</name><age>{age}</age></person>
p: scala.xml.Elem = <person><name>Bill</name><age>42</age></person>

In this example, the Scala variables name and age are put inside curly braces, inside the XML literals. The variable p in the REPL results shows that they’re translated to their values (Bill and 42, respectively). Methods and other expressions can be used in the same way.

This ability to weave Scala code and XML together is similar to using a templating system, and is a great way to generate dynamic XML output, including output like an RSS news feed, all forms of business data, or a simple XHTML UL/LI tag combination:

scala> val fruits = List("apple", "banana", "orange")
fruits: List[java.lang.String] = List(apple, banana, orange)

scala> val ul = <ul>{fruits.map(i => <li>{i}</li>)}</ul>
ul: scala.xml.Elem = <ul><li>apple</li><li>banana</li><li>orange</li></ul>

scala> println(ul)
<ul><li>apple</li><li>banana</li><li>orange</li></ul>

You can use the same technique to generate XHTML <select> and <option> tags, such as for a list of states or credit cards options, and any other form of XML data.

Discussion

As shown in the fruits example, XML literals can contains Scala code in curly braces, and that code can include additional XML literal values, which can contain Scala code. This nesting of Scala and XML can continue to go deeper, as needed.

To explain how this works, let’s look at the code again:

val ul = <ul>{fruits.map(i => <li>{i}</li>)}</ul>

Here’s how this code works:

  • The XML expression is enclosed in the matching <ul> tags.
  • The curly braces begin the fruits.map Scala expression.
  • <li> tags are embedded in the code block passed to the map method.
  • The variable i is enclosed in curly braces inside the <li> tags, where it will be replaced by its values as the map method executes.

If you’ve used XML/HTML templating tools previously, you can appreciate the power of this approach.

NodeBuffer

The NodeBuffer class provides another nice way to dynamically build XML. The following example shows how to build a set of <li> tags as a NodeBuffer, and then insert those elements into a final <ul>tag:

scala> val x = new xml.NodeBuffer
x: scala.xml.NodeBuffer = ArrayBuffer()

scala> x += <li>apple</li>
res0: x.type = ArrayBuffer(<li>apple</li>)

scala> x += <li>banana</li>
res1: x.type = ArrayBuffer(<li>apple</li>, <li>banana</li>)

scala> val ul = <ul>{x}</ul>
ul: scala.xml.Elem = <ul><li>apple</li><li>banana</li></ul>

NodeBuffer is a simple convenience class that extends ArrayBuffer[Node]. It adds one method named &+that appends the given object to the buffer, and returns a this reference for convenience. This lets you write a “fluent” style of code like this, if you prefer:

val nb = new xml.NodeBuffer
val nb2 = nb &+ <li>apple</li> &+ <li>banana</li> &+ <li>cherry</li>

See Recipe 5.9 of the Scala Cookbook, “Supporting a Fluent Style of Programming,” for more information on supporting and using this coding style.

Posted by 1010
00.scala2014. 3. 28. 13:43
반응형

After writing a Java REST (RESTful) client using Apache HttpClient, I turned around and modified that code to be a Scala REST client, also using the Apache HttpClient library.

Here then, without much introduction, is the source code for a Scala REST client example, which demonstrates how to read information from the Yahoo Weather API, which is actually an RSS feed. As a result, this example also demonstrates how to search an XML document for the information you want, using the built-in Scala XML parsing capabilities.

package tests

import java.io._
import org.apache.http.HttpEntity
import org.apache.http.HttpResponse
import org.apache.http.client.ClientProtocolException
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.DefaultHttpClient
import scala.collection.mutable.StringBuilder
import scala.xml.XML

object ScalaApacheHttpRestClient {

  def main(args: Array[String]) {
  
    // (1) get the content from the yahoo weather api url
    val content = getRestContent("http://weather.yahooapis.com/forecastrss?p=80020&u=f")
    
    // (2) convert it to xml
    val xml = XML.loadString(content)
    assert(xml.isInstanceOf[scala.xml.Elem])  // needed?

    // (3) search the xml for the nodes i want
    val temp = (xml \\ "channel" \\ "item" \ "condition" \ "@temp") text
    val text = (xml \\ "channel" \\ "item" \ "condition" \ "@text") text

    // (4) print the results
    val currentWeather = format("The current temperature is %s degrees, and the sky is %s.", temp, text.toLowerCase())
    println(currentWeather)
  }
  
  /**
   * Returns the text content from a REST URL. Returns a blank String if there
   * is a problem.
   */
  def getRestContent(url:String): String = {
    val httpClient = new DefaultHttpClient()
    val httpResponse = httpClient.execute(new HttpGet(url))
    val entity = httpResponse.getEntity()
    var content = ""
    if (entity != null) {
      val inputStream = entity.getContent()
      content = io.Source.fromInputStream(inputStream).getLines.mkString
      inputStream.close
    }
    httpClient.getConnectionManager().shutdown()
    return content
  }

}

Description

As you can see from the main method, the code is pretty simple, only involving a few steps. The getRestContent function does a lot of the dirty work involved in getting the content from a REST URL. (That function can probably be written better, as I'm ignoring a number of exceptions that can happen.)

There is also some magic involved in processing the XML using the Scala XML library. It took me longer to figure out the syntax to search the XML for the nodes I wanted than it did to write the rest of this example, so I'll discuss that Scala XML syntax in another tutorial.

As I mentioned in my earlier Java RESTful client example, there are several other good ways of creating REST clients in Java and Scala, including using the Jersey project, or the Apache CXF project. Those libraries are specifically geared more towards web services and implementing the API of the Java JSRs that describe web services, while the Apache HttpClient library just simplifies the process of creating HTTP clients. Which one you use is up to you, and I hope/plan to write RESTful clients in Scala using each of those libraries.

In trying to keep this short, I'll leave the example and discussion at that. As usual, if you have any questions, comments, or improvements, just leave a note in the comments section below.

Posted by 1010
00.scala2014. 3. 28. 13:42
반응형

Scala JDBC FAQ: How can I use the Java JDBC API in my Scala application?

If you want to use a SQL database with your Scala applications, it's good to know you can still use the traditional Java JDBC programming library to access databases. I just ran a simple JDBC connectionand SQL SELECT test, and everything seems to work just as it does in Java.

A Scala, JDBC, and MySQL example

Without any further introduction, here's the source code for a complete Scala class (an object, actually) that connects to a MySQL database using nothing but plain old JDBC. In this example I'm connecting to a MySQL database server on my local computer, and then running a SQL SELECT query against theuser table of the mysql database:

package jdbc

import java.sql.DriverManager
import java.sql.Connection

/**
 * A Scala JDBC connection example by Alvin Alexander,
 * http://alvinalexander.com
 */
object ScalaJdbcConnectSelect {

  def main(args: Array[String]) {
    // connect to the database named "mysql" on the localhost
    val driver = "com.mysql.jdbc.Driver"
    val url = "jdbc:mysql://localhost/mysql"
    val username = "root"
    val password = "root"

    // there's probably a better way to do this
    var connection:Connection = null

    try {
      // make the connection
      Class.forName(driver)
      connection = DriverManager.getConnection(url, username, password)

      // create the statement, and run the select query
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("SELECT host, user FROM user")
      while ( resultSet.next() ) {
        val host = resultSet.getString("host")
        val user = resultSet.getString("user")
        println("host, user = " + host + ", " + user)
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
  }

}

As you can see, this Scala JDBC database connection example looks just like Java JDBC, which you can verify from my very old JDBC connection example and JDBC SQL SELECT example.

If you're new to JDBC and the MySQL URL shown above looks weird because I'm accessing the "mysql" database in the MySQL database server, remember that the general MySQL connection URL looks like this:

val url = "jdbc:mysql://hostname/database_name"

and if I was instead connecting to a database named drupal7, the MySQL URL would look like this instead:

val url = "jdbc:mysql://localhost/drupal7"


Posted by 1010
00.scala2014. 3. 28. 13:41
반응형

Scala FAQ: Can you share some examples of using tuples in Scala?

Getting started with tuples

A Scala tuple is a class that can contain a miscellaneous collection of elements. I like to think of them as a little bag or container you can use to hold things and pass them around.

You create a tuple with the following syntax, enclosing its elements in parentheses. Here's a tuple that contains an Int and a String:

val stuff = (42, "fish")

This creates a specific instance of a tuple called a Tuple2, which we can demonstrate in the REPL:

scala> val stuff = (42, "fish")
stuff: (Int, java.lang.String) = (42,fish)

scala> stuff.getClass
res0: java.lang.Class[_ <: (Int, java.lang.String)] = class scala.Tuple2

A tuple isn't actually a collection; it's a series of classes named Tuple2Tuple3, etc., through Tuple22. You don't have to worry about that detail, other than knowing that you can have anywhere from two to twenty-two items in a tuple. (And in my opinion, if you have twenty-two miscellaneous items in a bag, you should probably re-think your design.)

Accessing tuple elements

You can access tuple elements using an underscore syntax. The first element is accessed with _1, the second element with _2, and so on, like this:

scala> val things = ("a", 1, 3.5)
things: (java.lang.String, Int, Double) = (a,1,3.5)

scala> println(things._1)
a

scala> println(things._2)
1

scala> println(things._3)
3.5

Use variable names to access tuple elements

When referring to a Scala tuple you can also assign names to the elements in the tuple. I like to do this when returning miscellaneous elements from a method. To demonstrate the syntax, let's create a very simple method that returns a tuple:

def getUserInfo = ("Al", 42, 200.0)

Now we can call that method, and assign the tuple results directly to variables, like this:

val(name, age, weight) = getUserInfo

Here's what this looks like in the REPL:

scala> def getUserInfo = ("Al", 42, 200.0)
getUserInfo: (java.lang.String, Int, Double)

scala> val(name, age, weight) = getUserInfo
name: java.lang.String = Al
age: Int = 42
weight: Double = 200.0

It's shown in the REPL results, but we'll further confirm that we can indeed access the values by variable name:

scala> name
res4: java.lang.String = Al

scala> age
res5: Int = 42

scala> weight
res6: Double = 200.0

That's pretty nice.

In a cool, related feature, if you only want to access some of the elements, you can ignore the others by using an underscore placeholder for the elements you want to ignore. Imagine you want to ignore theweight in our example:

scala> val(name, age, _) = getUserInfo
name: java.lang.String = Al
age: Int = 42

Or suppose you want to ignore the age and weight:

scala> val(name, _, _) = getUserInfo
name: java.lang.String = Al

Again, that's good stuff.

Iterating over a Scala tuple

As mentioned, a tuple is not a collection; it doesn't descend from any of the collection traits or classes. However, you can treat it a little bit like a collection by using its productIterator method.

Here's how you can iterate over the elements in a tuple:

scala> val t = ("Al", 42, 200.0)
t: (java.lang.String, Int, Double) = (Al,42,200.0)

scala> t.productIterator.foreach(println)
Al
42
200.0

The tuple toString method

The tuple toString method gives you a nice representation of a tuple:

scala> t.toString
res9: java.lang.String = (Al,42,200.0)

scala> println(t.toString)
(Al,42,200.0)

Creating a tuple with ->

In another cool feature, you can create a tuple using this syntax:

1 -> "a"

This creates a Tuple2, which we can demonstrate in the REPL:

scala> 1 -> "a"
res1: (Int, java.lang.String) = (1,a)

scala> res11.getClass
res2: java.lang.Class[_ <: (Int, java.lang.String)] = class scala.Tuple2

You'll see this syntax a lot when creating maps:

scala> val map = Map(1->"a", 2->"b")
map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b)


Posted by 1010
00.scala2014. 3. 28. 13:41
반응형

Scala Map FAQ: How can I iterate/loop over a Scala Map?

There are several different ways to iterate over a Scala Map, and the method you choose depends on the problem you need to solve.

To get started with our examples, let's create a simple Map we can work with:

scala> val m1 = Map("fname" -> "Al", "lname" -> "Alexander")

Iterating over Scala maps

Once you have a Map, you can iterate over it using several different techniques. For me, this is by far the easiest technique:

scala> for ((k,v) <- m1) printf("key: %s, value: %s\n", k, v)
key: fname, value: Al
key: lname, value: Alexander

This page has some other Map and for loop examples, which I've reproduced here:

// version 1 (tuples)
m1 foreach (x => println (x._1 + "-->" + x._2))

// version 2 (foreach and case)
m1 foreach {case (key, value) => println (key + "-->" + value)}

You can choose whatever format you prefer. Scala is beginning to remind me of the Perl slogan: "There's more than one way to do it", and this is good, because you can choose whichever approach makes the most sense for the problem at hand.

Scala Map, keys, foreach, and tuples

To demonstrate a more "real world" example of looping over a Scala Map, while working through some programming examples in the book, Programming Collective Intelligence, I decided to code them up in Scala, and I wanted to share the approaches I prefer using the Scala foreach and for loops.

To begin with, I defined my Scala Map like this:

val p1Ratings = Map("Lady in the Water"-> 3.0, 
                    "Snakes on a Plane"-> 4.0,
                    "You, Me and Dupree"-> 3.5)

In my case, when I'm iterating over the Map I'm really just interested in the Map keys, so the cleanest way to loop over every Map element is like this:

p1Ratings.keys.foreach( (movie) => 
  if (p2Ratings.contains(movie)) similarItems += (movie -> true)
)

While I chose that looping method in my code, I could also use the "tuples" approach, where movie is a Tuple, and I only use the first element of the Tuple, which happens to be my keys:

p1Ratings foreach ( (movie) => 
  if (p2Ratings.contains(movie._1)) similarItems += (movie._1 -> true)
)

In that approach, I ignore the second element of each Tuple, because I don't need it. (Which is why I don't like this approach for this instance.)

In a similar approach, I loop over the Map as shown next, creating a field named rating1 which I again don't use because I don't need it:

for ((movie1, rating1) <- p1Ratings) {
  if (p2Ratings.contains(movie1)) similarItems += (movie1 -> true)
}

These last two approaches will work better, and look a little more logical, if you need to access the key and value for each map element, but in my case, since I don't need to values, I'm using the first approach shown above.

Posted by 1010
00.scala2014. 3. 28. 13:40
반응형

Here's a quick look at how to use the Scala Map class, with a colllection of Map class examples.

The immutable Map class is in scope by default, so you can create an immutable map without an import, like this:

val states = Map("AL" -> "Alabama", "AK" -> "Alaska")

To create a mutable Map, import it first:

var states = scala.collection.mutable.Map("AL" -> "Alabama")

Adding, removing, and updating mutable Map elements

The following examples show how to add, remove, and update elements in a mutable Scala Map:

// create an empty map
var states = scala.collection.mutable.Map[String, String]()

// create a map with initial elements
var states = scala.collection.mutable.Map("AL" -> "Alabama", "AK" -> "Alaska")

// add elements with +=
states += ("AZ" -> "Arizona")
states += ("CO" -> "Colorado", "KY" -> "Kentucky")

// remove elements with -=
states -= "KY"
states -= ("AZ", "CO")

// update elements by reassigning them
states("AK") = "Alaska, The Big State"

Iterating over Scala maps

Once you have a Map, you can iterate over it using several different techniques. I prefer using the for loop (or for comprehension):

scala> val m1 = Map("fname" -> "Al", "lname" -> "Alexander")

scala> for ((k,v) <- m1) printf("key: %s, value: %s\n", k, v)
key: fname, value: Al
key: lname, value: Alexander

This page has some other Map and for loop examples, which I've reproduced here:

// version 1 (tuples)
m1 foreach (x => println (x._1 + "-->" + x._2))

// version 2 (foreach and case)
m1 foreach {case (key, value) => println (key + "-->" + value)}

You can choose whatever format you prefer.

A few more ways to iterate over a Scala Map

To demonstrate a more "real world" example of looping over a Scala Map, while I was working through some programming examples in the book, Programming Collective Intelligence, I decided to code them up in Scala.

To begin with, I defined my Scala Map like this:

val p1Ratings = Map("Lady in the Water"-> 3.0, 
                    "Snakes on a Plane"-> 4.0,
                    "You, Me and Dupree"-> 3.5)

In my case, when I'm iterating over the Map I'm really just interested in the Map keys, so the cleanest way to loop over every Map element is like this:

p1Ratings.keys.foreach( (movie) => 
  if (p2Ratings.contains(movie)) similarItems += (movie -> true)
)

While I chose that looping method in my code, I could also use the "tuples" approach, where movie is a Tuple, and I only use the first element of the Tuple, which happens to be my keys:

p1Ratings foreach ( (movie) => 
  if (p2Ratings.contains(movie._1)) similarItems += (movie._1 -> true)
)

In that approach, I ignore the second element of each Tuple, because I don't need it. (Which is why I don't like this approach for this instance.)

In a similar approach, I loop over the Map as shown next, creating a field named rating1 which I again don't use because I don't need it:

for ((movie1, rating1) <- p1Ratings) {
  if (p2Ratings.contains(movie1)) similarItems += (movie1 -> true)
}

These last two approaches will work better, and look a little more logical, if you need to access the key and value for each map element, but in my case, since I don't need to values, I'm using the first approach shown above.

Posted by 1010
00.scala2014. 3. 28. 13:40
반응형

The Scala List class filter method implicitly loops over the List you supply, tests each element of the List with the function you supply. Your function must return true or false, and filter returns the list elements where your function returns true.

(Note: Even though I use a List in these examples, the filter method can be used on any Scala sequence, including Array, List, Vector, Seq, etc.)

Let's look at a few simple examples. In this first example we filter a small list of numbers so that our resulting list only has numbers that are greater than 2:

scala> val nums = List(5, 1, 4, 3, 2)
nums: List[Int] = List(5, 1, 4, 3, 2)

scala> nums.filter(_ > 2)
res0: List[Int] = List(5, 4, 3)

Note that in the real world you'd assign the filtered results to a new List, like this:

val originalList = List(5, 1, 4, 3, 2)
val newList = originalList.filter(_ > 2)

This example shows how to get the even numbers from a List using a simple modulus test:

scala> nums.filter( _ % 2 == 0 )
res21: List[Int] = List(4, 2)

You can take that example a step further by filtering and then sorting the list:

# filter and sort
scala> nums.filter( _ % 2 == 0 ).sort(_ < _)
warning: there were 1 deprecation warnings; re-run with -deprecation for details
res22: List[Int] = List(2, 4)

filter method examples with a List of Strings

Here are two filter method examples with a list of Strings:

val fruits = List("orange", "peach", "apple", "banana")

scala> fruits.filter(_.length > 5)
res21: List[java.lang.String] = List(banana, orange)

scala> fruits.filter(_.startsWith("a"))
res22: List[java.lang.String] = List(apple)

Combining filter, sort, and map

From the excellent book, Beginning Scala, here's a nice combination of the List filter, sort, and map methods:

trait Person {
  def first: String
  def age: Int
  def valid: Boolean
}

Returns the first name of 'valid' persons, sorted by age

def validByAge(in: List[Person]) =
  in.filter(_.valid).
  sort(_.age < _.age).
  map(_.first)

The following example shows how you can use filter with map to transform the type of data that the expression returns. In this case we'll start with a sequence of Person objects, and transform it into a sequence of String objects.

We'll start with a simple case class:

scala> case class Person(first: String, last: String, mi: String)
defined class Person

Next, we'll create a little sequence of Person objects:

scala> val fred = Person("Fred", "Flintstone", "J")
fred: Person = Person(Fred,Flintstone,J)

scala> val wilma = Person("Wilma", "Flintstone", "A")
wilma: Person = Person(Wilma,Flintstone,A)

scala> val barney = Person("Barney", "Rubble", "J")
barney: Person = Person(Barney,Rubble,J)

scala> val betty = Person("Betty", "Rubble", "A")
betty: Person = Person(Betty,Rubble,A)

scala> val peeps = Seq(fred, wilma, barney, betty)
peeps: Seq[Person] = List(Person(Fred,Flintstone,J), Person(Wilma,Flintstone,A), Person(Barney,Rubble,J), Person(Betty,Rubble,A))

Finally, we'll combine filter and map to get a list of all first names where the last name is "Flintstone":

scala> peeps.filter(_.last == "Flintstone").map(_.first)
res0: Seq[String] = List(Fred, Wilma)

The way this works is:

  • The filter method returns a sequence of Person objects where the last name is "Flintstone".
  • The map method call gets the first name of each Person object. This results in a sequence of strings, where each string is the first name of each person that came out of the filter call.

I initially wrote this as a for/yield loop, but then realized I could write this much more concisely with this approach. At the moment I find the for/yield loop to be more readable, and this to be much more concise.

In my opinion, this code can be made a little more readable by using a variable name in the mapexpression, as a reminder that you're still dealing with Person objects:

scala> peeps.filter(_.last == "Flintstone").map(person => person.first)
res1: Seq[String] = List(Fred, Wilma)

Scala List filter method summary

I hope these filter method examples have been helpful. Here's a quick summary of how the filter method works:

  • filter implicitly loops over a List.
  • filter takes a function as an argument. That function should take one List element as input, perform the test you define, and then return either true or false (a Boolean).
  • filter only returns List elements that match the filtering expression.


Posted by 1010
00.scala2014. 3. 28. 13:39
반응형

Scala List FAQ: Can you share some Scala List class examples?

The Scala List class may be the most commonly used data structure in Scala applications. Therefore, it's very helpful to know how create lists, merge lists, select items from lists, operate on each element in a list, and so on.

In this tutorial, I'll try to share examples of the most common List operations (methods).

Scala List class - Introduction

The Scala List class (scala.List) holds a sequenced, linear list of items. In a List, each element must be of the same type.

At some point I'll add a class diagram here, but until then, here's a simplified version of the Scala List class hierarchy:

  • The scala.List class is a pointer to the scala.collection.immutable.List class.
  • The List class extends LinearSeq with Product (and some others).
  • The trait LinearSeq extends Seq
  • The trait Seq extends Iterable
  • Iterable extends trait Traversable

(I need to update this, but this is the Scala class hierarchy, as shown by the current Scala API documentation.

Creating a Scala List object

You can create a Scala List object in several different way. Here's the Lisp-style approach to creating a List:

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

Here's the Java-style approach to creating a Scala List:

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

A few notes about these approaches:

  • The first approach shows the "cons" syntax, which, as I mentioned, is the Lisp style of creating a list.
  • The :: method takes two arguments, a "head", which is a single element, and a "tail", which is a List.
  • As you can see, Scala can usually infer the type of a List very well.

If you're mixing types in a List constructor, you may need to manually specify the List type. This example demonstrates that syntax:

scala> val x = List[Number](1, 2.0, 33d, 0x1)
x: List[java.lang.Number] = List(1, 2.0, 33.0, 1)

In this example, I'm explicitly saying that I want the values in the List to be saved as the Number type.

The List range method

You can also create a List with the List's range method:

scala> val x = List.range(1,10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

The range function can also take a third argument which serves as a "step" value when creating the List:

scala> val x = List.range(0,10,2)
x: List[Int] = List(0, 2, 4, 6, 8)

The List fill method

You can also create a new List with the fill method:

scala> val x = List.fill(3)("foo")
x: List[java.lang.String] = List(foo, foo, foo)

The List tabulate method

Finally, you can create a new List with the tabulate method of the List class. The tabulate method creates a new List whose elements are created according to the function you supply. The book Programming in Scala shows how to create a List using a simple "squares" function:

scala> val x = List.tabulate(5)(n => n * n)
x: List[Int] = List(0, 1, 4, 9, 16)

As you can see, that example creates a List of five elements, where the element values are the square of the index of each element (0 becomes 0, 1 becomes 1, 2 becomes 4, 3 becomes 9, and 4 becomes 16).

In summary, you can create a new Scala List with these approaches:

  • Lisp style
  • Java style
  • range method
  • tabulate method

Prepend items to a List

You can prepend items to a Scala List using the :: method:

// create a List
scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)

// prepend an element to the list
scala> val y = 0 :: x
y: List[Int] = List(0, 1, 2, 3)

According to the Beginning Scala book (and several other sources), prepending items to a list is a "very fast, constant-time, O(1) operation."

(Again, I recall this approach and syntax from using Lisp many years ago.)

Appending and merging Lists

There are at least two ways to merge Scala Lists. First, you can merge two Scala lists using the ::: method of the List class:

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

scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)

scala> val c = a ::: b
c: List[Int] = List(1, 2, 3, 4, 5, 6)

This operation is said to have O(n) speed, where n is the number of elements in the first List.

You can also merge two Scala lists using the List's concat method:

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

scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)

scala> val c = List.concat(a, b)
c: List[Int] = List(1, 2, 3, 4, 5, 6)

Iterating lists with foreach

A very common way to iterate over Scala lists is with the foreach method. Here's a quote about the foreach method from the book Programming in Scala:

foreach takes a procedure (a function with a result type Unit) as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.

Here's a simple example showing how to use the foreach function to print every item in a List:

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

scala> x.foreach { println }
1
2
3

This next example shows a way to sum all the elements in a list using the foreach method:

scala> var sum = 0
sum: Int = 0

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

scala> x.foreach(sum += _)

scala> println(sum)
6

Scala Lists and the for comprehension

The Scala for comprehension is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for comprehension:

scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim")
names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim)

scala> for (name <- names) println(name)
Bob
Fred
Joe
Julia
Kim

So far, so good. Now let's add a simple "if" clause to the for comprehension to print only the elements we want to print:

scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim")
names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim)

scala> for (name <- names if name.startsWith("J"))
     | println(name)
Joe
Julia

If you already know about the for comprehension, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.

Before leaving, I will add these notes however, from the book Programming in Scala:

Scala provides the for comprehension, which provides syntactically pleasing nesting of map, flatMap, and filter ... The for comprehension is not a looping construct, but is a syntactic construct the compiler reduces to map, flatMap, and filter.

Filtering Scala lists

A great thing about Scala is that it is a functional programming language. In the next examples we'll show some of the power of functional programming. In this section we'll focus on the filter method of the List class.

scala> val x = List(1,2,3,4,5,6,7,8,9,10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// create a list of all the even numbers in the list
scala> val evens = x.filter(a => a % 2 == 0)
evens: List[Int] = List(2, 4, 6, 8, 10)

takeWhile

scala> val x = List(1,2,3,4,5,6,7,8,9,10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val y = x.takeWhile(a => a < 6)
y: List[Int] = List(1, 2, 3, 4, 5)

Other list filtering methods:

partition - returns a pair of lists, one where the predicate is true,
            the other where the predicate is false
find      - returns the first element matching a predicate (as opposed to
            returning all such elements)

Others:   takeWhile, dropWhile, span

The List map function

The Scala List map function "transforms each element of a collection based on a function."

Here are a few map examples. First, doubling every item in a List:

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

scala> val y = x.map(a => a * 2)
y: List[Int] = List(2, 4, 6)

Here's a slightly simpler version of that map example, using the Scala wildcard character (_) instead of a fake variable name:

scala> val y = x.map(_ * 2)
y: List[Int] = List(2, 4, 6)

Here's an example using a list of strings:

scala> val names = List("Fred", "Joe", "Bob")
names: List[java.lang.String] = List(Fred, Joe, Bob)

scala> val lower = names.map(_.toLowerCase)
lower: List[java.lang.String] = List(fred, joe, bob)

scala> val upper = names.map(_.toUpperCase)
upper: List[java.lang.String] = List(FRED, JOE, BOB)

A very nice example in the book Beginning Scala demonstrates how to convert a List into something useful in the HTML world, a list of <li> elements using the map function:

scala> val names = List("Fred", "Joe", "Bob")
names: List[java.lang.String] = List(Fred, Joe, Bob)

scala> val li = names.map(name => <li>{name}</li>)
li: List[scala.xml.Elem] = List(<li>Fred</li>, <li>Joe</li>, <li>Bob</li>)

As you can see, you can rapidly build a lot of functionality in just a little bit of code.

Sorting Scala Lists

I need to research why this code is deprecated, but for the time being, here's an example of how to sort a Scala List:

scala> val x = List(10, 2, 5)
x: List[Int] = List(10, 2, 5)

scala> val y = x.sort(_ < _)
warning: there were 1 deprecation warnings; re-run with -deprecation for details
y: List[Int] = List(2, 5, 10)

(TODO: Research the correct, current approach for sorting Scala lists.)

Scala List class and pattern matching

You can use the List class with the Scala pattern matching and case/match syntax. I'll add examples here as I create them in my own code. (TODO)

Other Scala List functions

The Scala List class has an incredible number of functions/methods, and over time I'll attempt to document them all. In the meantime, here's a short list of the many other Scala List methods I don't have examples for at this time:

length  - returns the length of a List
head    - returns the first element of a List
last    - returns the last element of a List
init    - returns a List consisting of all elements except the last one
tail    - returns every elements of a List except the first element
isEmpty - returns a Boolean indicating if the List is empty

reverse - returns a reversed version of the List
flatten - takes a list of lists and flattens it out to a single list

mkString - converts a List to a String

iterator
toArray

foldLeft
reduceLeft

map
flatMap
foreach

forall
exists

Folding lists: /: and :\

sortWith

Again, I'll try to add examples of these List methods over time. (TODO)

Relatives of the Scala List

There are times you may want to use one of the relatives of the Scala List class, instead of using the List class itself. I'll add more to this over time, but for now, here are a few links:


Posted by 1010
00.scala2014. 3. 28. 13:38
반응형

Scala List class FAQ: How do I create a List inScala?

You can create a Scala List in several different ways, including these approaches:

  • Lisp style
  • Java style
  • Using the List class range method
  • Using the List class fill method
  • Using the List class tabulate method

In this Scala List tutorial, I'll demonstrate each of these approaches. I'll execute each command in the Scala command-line interpreter so you can see the results of each approach.

Create a Scala List in the Lisp style

First, if you prefer the Lisp-style of programming, you can create a Scala List using the "cons" syntax, like this:

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

As you can see, this creates a List that contains the Ints 1, 2, and 3. With this approach, you need to end the list with the Nil object.

In this "cons" style, the :: method takes two arguments, a "head", which is a single element, and a "tail", which is a List. (And yes, "::" is a function/method.)

Create a Scala List in the Java style

My guess is that the most popular way to create a List is with what I call the "Java style":

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

This syntax looks a lot like the Java way to create an object, except (a) you don't need the "new" keyword before the List, and (b) you don't have to declare the type of elements in the List.

Note that if you're going to mix types in a List constructor, you may need to manually specify the type of the List. This example demonstrates the syntax to specify the List type:

scala> val x = List[Number](1, 2.0, 33d, 0x1)
x: List[java.lang.Number] = List(1, 2.0, 33.0, 1)

In this example I've explicitly stated that the values in the List are of the Number type.

Create a Scala List with the range method

Another convenient way to create a List is with the List class range method:

scala> val x = List.range(1, 10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

As you can see, this example created a List of Int values, beginning at 1, and ending at 9.

In addition to this simple approach, the range function can also take a third argument, which serves as a "step" value when creating the List:

scala> val x = List.range(0, 10, 2)
x: List[Int] = List(0, 2, 4, 6, 8)

Create a Scala List with the List class fill method

Another convenient way to create a Scala List is with the List class fill method:

scala> val x = List.fill(3)("foo")
x: List[java.lang.String] = List(foo, foo, foo)

As you can see, you just specify how many items you want, and the object value you want to fill each List element with.

Create a Scala List with the List class tabulate method

Finally, you can create a Scala List with the tabulate method of the List class.

The tabulate method creates a new List whose elements are created according to the function you supply. The excellent book "Programming in Scala" shows how to create a List using a simple "squares" function with the tabulate method:

scala> val x = List.tabulate(5)(n => n * n)
x: List[Int] = List(0, 1, 4, 9, 16)

As you can see, that example creates a List of five elements, where the element values are the square of the index of each element, so 0 becomes 0, 1 becomes 1, 2 becomes 4, 3 becomes 9, and 4 becomes 16.

Creating Scala Lists - Summary

In summary, as you have seen, you can create Scala lists in several different ways, including these approaches:

  • Lisp style
  • Java style
  • Using the List class range method
  • Using the List class fill method
  • Using the List class tabulate method

I hope this Scala List class tutorial has been helpful.

Posted by 1010
00.scala2014. 3. 28. 13:37
반응형

Scala List FAQ: How do I merge Scala Lists?

There are at least three ways to merge/concatenate Scala List instances, as shown in the examples below.

1) The Scala List ::: method

First, you can merge two Scala lists using the ::: method of the List class, as demonstrated here at theScala command prompt:

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

scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)

scala> val c = a ::: b
c: List[Int] = List(1, 2, 3, 4, 5, 6)

This operation is said to have O(n) speed, where n is the number of elements in the first List.

2) The Scala List concat method

You can also merge two Scala lists using the List class concat method:

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

scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)

scala> val c = List.concat(a, b)
c: List[Int] = List(1, 2, 3, 4, 5, 6)

3) The Scala List ++ method

You can also use the List ++ method to concatenate Scala Lists, as shown here:

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

scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)

scala> val c = a ++ b
c: List[Int] = List(1, 2, 3, 4, 5, 6)

I'll try to add more information on these three approaches as I learn about them, but for now, I just wanted to share these three approaches.

Posted by 1010
00.scala2014. 3. 28. 13:37
반응형

Scala List/foreach FAQ: How do I iterate over a Scala List using the foreach method and for loop?

There are a number of ways to iterate over a Scala List using the foreach operator and for comprehension, and I'll show a few of those approaches here.

Iterating lists with foreach

A common way to iterate over a Scala List is with the foreach method. Here's a quote about the foreach method from the book Programming in Scala:

foreach takes a procedure (a function with a result type Unit) as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.

Here's a simple example showing how to use the foreach function to print every item in a List:

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

scala> x.foreach { println }
1
2
3

If you've used a programming language like Ruby, this syntax will look very familiar to you.

This next example shows a way to sum all the elements in a list using the foreach method:

scala> var sum = 0
sum: Int = 0

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

scala> x.foreach(sum += _)

scala> println(sum)
6

Scala Lists and the for comprehension

The Scala for comprehension is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for comprehension:

scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim")
names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim)

scala> for (name <- names) println(name)
Bob
Fred
Joe
Julia
Kim

So far, so good. Now let's add a simple "if" clause to the for comprehension to print only the elements we want to print:

scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim")
names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim)

scala> for (name <- names if name.startsWith("J"))
     | println(name)
Joe
Julia

If you already know about the for comprehension, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.

Before leaving, I will add these notes however, from the book Programming in Scala:

Scala provides the for comprehension, which provides syntactically pleasing nesting of map, flatMap, and filter ... The for comprehension is not a looping construct, but is a syntactic construct the compiler reduces to map, flatMap, and filter.


Posted by 1010
00.scala2014. 3. 28. 13:36
반응형

Scala collections FAQ: How can I convert a Scala array to a String?

A simple way to convert a Scala array to a String is with the mkString method of the Array class. (Although I've written "array", the same technique also works with any Scala sequence, including Array, List, Seq, ArrayBuffer, Vector, and other sequence types.)

Here's a quick array to string example using the Scala REPL:

scala> val args = Array("Hello", "world", "it's", "me")
args: Array[java.lang.String] = Array(Hello, world, it's, me)

scala> val string = args.mkString(" ")
string: String = Hello world it's me

In this first statement:

val args = Array("Hello", "world", "it's", "me")

I create a Scala array named args, and in this second statement:

val string = args.mkString(" ")

I create a new String variable named string, separating each String in the array with a space character, which I specified when calling the mkString function.

Using other separator strings

Note that I could have given the mkString function any String to use as a separating character, like this:

scala> val string = args.mkString("\n")
string: String = 
Hello
world
it's
me

or like this:

scala> val string = args.mkString(" . ")
string: String = Hello . world . it's . me

Converting a Scala Int array to a String

As a final example, you can also use the Scala mkString method to convert an Int array to a String, like this:

scala> val numbers = Array(1,2,3)
numbers: Array[Int] = Array(1, 2, 3)

scala> val string = numbers.mkString(", ")
string: String = 1, 2, 3

In summary, I hope these Scala "Array to String" examples have been helpful.


Posted by 1010
00.scala2014. 3. 28. 13:36
반응형

Scala Map FAQ: How can I iterate/loop over a Scala Map?

There are several different ways to iterate over a Scala Map, and the method you choose depends on the problem you need to solve.

To get started with our examples, let's create a simple Map we can work with:

scala> val m1 = Map("fname" -> "Al", "lname" -> "Alexander")

Iterating over Scala maps

Once you have a Map, you can iterate over it using several different techniques. For me, this is by far the easiest technique:

scala> for ((k,v) <- m1) printf("key: %s, value: %s\n", k, v)
key: fname, value: Al
key: lname, value: Alexander

This page has some other Map and for loop examples, which I've reproduced here:

// version 1 (tuples)
m1 foreach (x => println (x._1 + "-->" + x._2))

// version 2 (foreach and case)
m1 foreach {case (key, value) => println (key + "-->" + value)}

You can choose whatever format you prefer. Scala is beginning to remind me of the Perl slogan: "There's more than one way to do it", and this is good, because you can choose whichever approach makes the most sense for the problem at hand.

Scala Map, keys, foreach, and tuples

To demonstrate a more "real world" example of looping over a Scala Map, while working through some programming examples in the book, Programming Collective Intelligence, I decided to code them up in Scala, and I wanted to share the approaches I prefer using the Scala foreach and for loops.

To begin with, I defined my Scala Map like this:

val p1Ratings = Map("Lady in the Water"-> 3.0, 
                    "Snakes on a Plane"-> 4.0,
                    "You, Me and Dupree"-> 3.5)

In my case, when I'm iterating over the Map I'm really just interested in the Map keys, so the cleanest way to loop over every Map element is like this:

p1Ratings.keys.foreach( (movie) => 
  if (p2Ratings.contains(movie)) similarItems += (movie -> true)
)

While I chose that looping method in my code, I could also use the "tuples" approach, where movie is a Tuple, and I only use the first element of the Tuple, which happens to be my keys:

p1Ratings foreach ( (movie) => 
  if (p2Ratings.contains(movie._1)) similarItems += (movie._1 -> true)
)

In that approach, I ignore the second element of each Tuple, because I don't need it. (Which is why I don't like this approach for this instance.)

In a similar approach, I loop over the Map as shown next, creating a field named rating1 which I again don't use because I don't need it:

for ((movie1, rating1) <- p1Ratings) {
  if (p2Ratings.contains(movie1)) similarItems += (movie1 -> true)
}

These last two approaches will work better, and look a little more logical, if you need to access the key and value for each map element, but in my case, since I don't need to values, I'm using the first approach shown above.

Posted by 1010
00.scala2014. 3. 28. 13:35
반응형

Scala List/foreach FAQ: How do I iterate over a Scala List using the foreach method and for loop?

There are a number of ways to iterate over a Scala List using the foreach operator and for comprehension, and I'll show a few of those approaches here.

Iterating lists with foreach

A common way to iterate over a Scala List is with the foreach method. Here's a quote about the foreach method from the book Programming in Scala:

foreach takes a procedure (a function with a result type Unit) as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.

Here's a simple example showing how to use the foreach function to print every item in a List:

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

scala> x.foreach { println }
1
2
3

If you've used a programming language like Ruby, this syntax will look very familiar to you.

This next example shows a way to sum all the elements in a list using the foreach method:

scala> var sum = 0
sum: Int = 0

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

scala> x.foreach(sum += _)

scala> println(sum)
6

Scala Lists and the for comprehension

The Scala for comprehension is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for comprehension:

scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim")
names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim)

scala> for (name <- names) println(name)
Bob
Fred
Joe
Julia
Kim

So far, so good. Now let's add a simple "if" clause to the for comprehension to print only the elements we want to print:

scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim")
names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim)

scala> for (name <- names if name.startsWith("J"))
     | println(name)
Joe
Julia

If you already know about the for comprehension, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.

Posted by 1010
00.scala2014. 3. 28. 13:34
반응형

Here's a quick look at how to create a multi-dimensional array in Scala, in this case a 2D array (matrix), and then access the array elements. As you can see, these commands were issued using the Scala REPL, and I've added a few comments to them:

// create a 2D array
scala> val matrix = Array.ofDim[Int](2,2)
matrix: Array[Array[Int]] = Array(Array(0, 0), Array(0, 0))

// populate the array elements
scala> matrix(0)(0) = 0

scala> matrix(0)(1) = 1

scala> matrix(1)(0) = 2

scala> matrix(1)(1) = 3

// access a couple of array elements
scala> matrix(0)(1)
res4: Int = 1

scala> matrix(1)(0)
res5: Int = 2

If you ever need to create a multidimensional array in Scala, I hope this example is helpful.

Posted by 1010
00.scala2014. 3. 28. 13:34
반응형

While working on a new Scala application, I just ran into a situation where a Java class I was using returned a Java List to me. I wasn't exactly thinking too hard at that moment, and didn't realize it was actually a Java List until I tried to use the foreach method on it, and Eclipse balked at me.

Suddenly I ran into a common problem in Scala: When you're using Java classes from Scalaapplications, those Java class will return Java collections. You can then either use them as the Java collections that they are (such as using a Java Iterator), or cast them to Scala collections.

Easily converting Java collections to Scala collections

Amazingly, to use methods like foreach, map, filter, find, and so on with my Java List, all I had to do was add this one import statement to my Scala application:

import scala.collection.JavaConversions._

Once I did that, I could suddenly use a foreach method on my List.

Let's take a quick look at how this works with the Scala command line tool (the Scala REPL). First, we'll create a java.util.List as normal, and see what the REPL shows:

scala> var list = new java.util.ArrayList[Int]()
list: java.util.ArrayList[Int] = []

scala> list.add(1)
res1: Boolean = true

scala> list.add(2)
res2: Boolean = true

Now, if I try to use the foreach method on the Java list, it will fail, as expected:

scala> list.foreach
<console>:9: error: value foreach is not a member of java.util.ArrayList[Int]
             list.foreach
                   ^

However, if I now add the magic JavaConversions import statement to my Scala code:

import scala.collection.JavaConversions._

I can then "magically" use the foreach method on my Java List object:

list.foreach { i => println(i) }
1
2

Scala, Java List, foreach, map, filter - How it works

I just started learning Scala in 2011, and it looks like programmers long before me realized the need for the Java to Scala collection conversions, and added this functionality in Scala 2.8. I haven't dug into the source code behind the scenes to see how this magic works, but I just found a nice discussion of the background at the Graham Hacking Scala website.

Graham mentions several interesting points in that article, including these notes:

If we look a bit further into the Scala API, we'll see that there's also a trait called Seq, which is a slightly better parallel to Java's List than the Iterable or Traversable traits. So what you really want to end up with when you bring your Java List into your Scala code is a Scala Seq, not a Scala List.

Conversions between Java and Scala collections with JavaConversions

While I'm on this topic, I'll conclude with a few links to the Scala website, where you can find more information:

As you can see from that second link, the JavaConversions object currently supports the following Java to Scala collections conversions:

scala.collection.Iterable <=> java.lang.Iterable
scala.collection.Iterable <=> java.util.Collection
scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set <=> java.util.Set
scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap

Important for my current project, the following one-way conversions are also offered:

scala.collection.Seq         => java.util.List
scala.collection.mutable.Seq => java.util.List
scala.collection.Set         => java.util.Set
scala.collection.Map         => java.util.Map
java.util.Properties         => scala.collection.mutable.Map[String, String]

In summary, I hope this brief tutorial on converting Java collections, such as a List, to Scala collections, has been helpful.

Posted by 1010
00.scala2014. 3. 28. 13:27
반응형

Scala FAQ: What are the Scala data types? How many bits do they use to store their data, and what is the range of those data types?

Courtesy of the excellent book, Programming in Scala, here is a list and description of the Scala data types, including bit sizes and data ranges:

Data Type     Definition

Boolean       true or false

Byte          8-bit signed two's complement integer (-2^7 to 2^7-1, inclusive)
Short         16-bit signed two's complement integer (-2^15 to 2^15-1, inclusive)
Int           32-bit two's complement integer (-2^31 to 2^31-1, inclusive)
Long          64-bit two's complement integer (-2^63 to 2^63-1, inclusive)

Float         32-bit IEEE 754 single-precision float
Double        64-bit IEEE 754 double-precision float

Char          16-bit unsigned Unicode character (0 to 2^16-1, inclusive)
String        a sequence of Chars

Notes about Scala data types

The String class resides in the package java.lang, and all these other types are in the package scala.

You may have noticed that these data types in Scala have the exact same range as the corresponding data types in Java. This makes it easy to convert these Scala types to their corresponding Java primitive types.

Also interesting to note, if you're into specifics: Collectively, Byte, Short, Int, Long, and Char are calledintegral types. The integral types plus Float and Double are called numeric types. (That was again courtesy of the book, Programming in Scala.)

Official Scala data type documentation

Here are links to the official Scala docs for these data types:

And here's a link to the Programming in Scala book on Amazon:

Posted by 1010
00.scala2014. 3. 28. 13:21
반응형

Scala collections FAQ: How can I convert a Scala array to a String?

A simple way to convert a Scala array to a String is with the mkString method of the Array class. (Although I've written "array", the same technique also works with any Scala sequence, including Array, List, Seq, ArrayBuffer, Vector, and other sequence types.)

Here's a quick array to string example using the Scala REPL:

scala> val args = Array("Hello", "world", "it's", "me")
args: Array[java.lang.String] = Array(Hello, world, it's, me)

scala> val string = args.mkString(" ")
string: String = Hello world it's me

In this first statement:

val args = Array("Hello", "world", "it's", "me")

I create a Scala array named args, and in this second statement:

val string = args.mkString(" ")

I create a new String variable named string, separating each String in the array with a space character, which I specified when calling the mkString function.

Using other separator strings

Note that I could have given the mkString function any String to use as a separating character, like this:

scala> val string = args.mkString("\n")
string: String = 
Hello
world
it's
me

or like this:

scala> val string = args.mkString(" . ")
string: String = Hello . world . it's . me

Converting a Scala Int array to a String

As a final example, you can also use the Scala mkString method to convert an Int array to a String, like this:

scala> val numbers = Array(1,2,3)
numbers: Array[Int] = Array(1, 2, 3)

scala> val string = numbers.mkString(", ")
string: String = 1, 2, 3

In summary, I hope these Scala "Array to String" examples have been helpful.

Posted by 1010
00.scala2014. 3. 28. 13:20
반응형

Scala array FAQ: How do I create a String array in Scala?

There are a few different ways to create String arrays in Scala. If you know all your array elements initially, you can create a Scala string array like this:

val fruits = Array("Apple", "Banana", "Orange")

If you don't know the strings that you want in your array initially, but know the size of your array, you can create it first, then populate it later, like this:

val fruits = new Array[String](3)

// somewhere later in the code ...

fruits(0) = "Apple"
fruits(1) = "Banana"
fruits(2) = "Orange"

Mutable Scala String arrays

Note that if you want to create a mutable Scala String array, you really want to use the Scala ArrayBufferclass instead of the Array class, like this:

import scala.collection.mutable.ArrayBuffer
var fruits = ArrayBuffer[String]()
fruits += "Apple"
fruits += "Banana"
fruits += "Orange"

See my Mutable Scala arrays (adding elements to arrays) tutorial for more information on using the Scala ArrayBuffer.

I can add more Scala String array syntax examples over time, but for now, those are the two most common approaches I know.

Posted by 1010
00.scala2014. 3. 28. 13:19
반응형

Just a quick note today that if you want to create a mutable Scala array -- particularly an array that can grow in size after you first declare it -- you need to use the Scala ArrayBuffer class instead of the Array class, which can't grow.

Here's a short example of how to instantiate an ArrayBuffer object, then add elements to the array:

import scala.collection.mutable.ArrayBuffer

var fruits = ArrayBuffer[String]()
fruits += "Apple"
fruits += "Banana"
fruits += "Orange"

Once you have an ArrayBuffer object, you can generally use it like an Array, getting elements like this:

println(fruits(0))

getting the array length like this:

println(fruits.length)

and so on.

Again, the only trick here is knowing that you can't add elements to a Scala array, and therefore, if you want to grow an array, you need to use the ArrayBuffer class instead.

Posted by 1010
00.scala2014. 3. 28. 13:19
반응형

Sometimes when you're writing Scala code, you need to create a null variable (a var, not a val), such as when you need to declare a variable right before using it in a try, catch, finally block. I just ran into this when writing a Scala IMAP email client, where I needed to create two variables right before the trydeclaration, so I could reference the fields in the try block and also in the finally block.

The way you declare a null var variable in Scala is like this:

var store: Store = null
var inbox: Folder = null

As you can see from that code, the secret is knowing that you have to assign the type to the variable when you declare it. If you don't do this, Scala won't know the data type of the variable, so it won't allow you to do this, but if you do it, Scala will be happy.

A complete example

As for my specific problem -- needing to declare a Scala variable right before a try/catch/finally clause -- here's what the solution looks like:

// (1) declare the null variables
var store: Store = null
var inbox: Folder = null

try {
  // (2) use the variables/fields in the try block
  store = session.getStore("imaps")
  inbox = getFolder(store, "INBOX")
  // rest of the code here ...
  catch {
    case e: NoSuchProviderException =>  e.printStackTrace()
                                        System.exit(1)
    case me: MessagingException =>      me.printStackTrace()
                                        System.exit(2)
} finally {
  // (3) use the variables/fields in the finally clause
  inbox.close
  store.close
}

In summary, I hope this short example of how to declare an empty/null variable before a try/catch block in Scala has been helpful.

Posted by 1010
00.scala2014. 3. 28. 13:13
반응형

Scala FAQ: Can you share some examples of the Scala try/catch/finally syntax? Also, can you show how to catch multiple exceptions, and just one exception with the Scala wildcard operator (_)?

The general Scala try/catch/finally syntax looks like this:

try
{
  // your scala code here
} 
catch
{
  case foo: FooException => handleFooException(foo)
  case bar: BarException => handleBarException(bar)
  case _ => println("Got some other kind of exception")
}
finally
{
  // your scala code here, such as to close a database connection
}

As you can see, the Scala try-catch-finally syntax is similar to the Java try-catch-finally syntax, except for the catch area, which uses Scala's pattern matching capabilities to handle the different exceptions you might run into.

In that example, I'm intentionally catching a FooException and a BarException, and then I'm using the Scala "_" wildcard operator to catch any other exceptions that might occur.

Using the Scala _ wildcard operator in a catch clause

One drawback of using Scala's wildcard character (_) in a catch clause is that you can't refer to it in your code, such as if you want to print the exception.

In the excellent book, Programmming Scala, the authors suggest naming your exception variable instead of using the wildcard, which you can then refer to in your own code, something like this:

try
{
  // your scala code here
} 
catch
{
  case foo: FooException => handleFooException(foo)
  case bar: BarException => handleBarException(bar)
  
  // handling any other exception that might come up
  case unknown => println("Got this unknown exception: " + unknown)
}
finally
{
  // your scala code here, such as to close a database connection
}

As you can see from that code, I just name a variable "unknown", which I can then refer to by name.

Printing a Scala exception's stack trace

Finally, here's another Scala try/catch example, where I demonstrate how to print the stack trace from an exception:

def runAppleScriptCommand(c: AppleScriptCommand) {
  val scriptEngineManager = new ScriptEngineManager
  val appleScriptEngine = scriptEngineManager.getEngineByName("AppleScript")
  try {
    appleScriptEngine.eval(c.command)
  } catch {
    case e: ScriptException => e.printStackTrace
  }
}

Scala try/catch/finally examples - Summary

I hope these examples of the Scala try/catch/finally syntax have been helpful. As usual, if you have any questions, comments, corrections, or better examples, just leave a note in the comments section below.

Posted by 1010
00.scala2014. 3. 28. 13:12
반응형

I haven't had the need for this syntax yet, but I just saw some code that shows how to create a private primary constructor in Scala, and I thought I'd test it and share an example of it.

In the example below, I've made the primary constructor of the Order class private:

object PrivateConstructorTests {

  def main(args: Array[String]) {
    val o = new Order  // this won't compile
  }

}

// note the 'private' keyword here
class Order private() {
  
  def this(orderId: Long) {
    this();
    // more code here ...
  }  
  
}

Private primary constructor syntax

The primary constructor is made private in this unusual looking line of code:

class Order private() {

This syntax might make a little more sense if I show a primary constructor that takes a parameter:

class Order private(customerId: Long) {

In either case, the "private" keyword in the location shown makes the primary constructor private.

Getting back to the first source code example, as you saw from the comment included in the source code, this line of code won't even compile because the primary constructor is private:

val o = new Order  // this won't compile

Again, I haven't had a need to use this Scala "private constructor" syntax yet, but I used to use it in Java when I wanted to enforce the Singleton Pattern, as is done in the Java Calendar class.

Posted by 1010
00.scala2014. 3. 28. 13:10
반응형

Scala offers a cool feature where you can rename a class when you import it, including both Scala and Java classes. The basic syntax to rename a class on import looks like this:

import scala.collection.mutable.{Map => MMap}

and this:

import java.util.{HashMap => JavaMap}

If all you needed to know, I hope those "rename on import" syntax examples were helpful.

Why rename a class on import?

An interesting question is, "Why would I want to rename a class on import?"

I've found that I do it to avoid namespace collisions, and/or to make things more clear. For instance, inScala the immutable Map class is imported by default, and if you want to use the mutable version you have to import it manually, as shown here:

# using Map w/o an import gives you an immutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

# after the import, the same syntax gives you a mutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.mutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

This can seem confusing, so one way to work around this confusion -- and make your code more obvious -- is to rename the mutable Map class when you import it. Here's a similar example, but in this case I rename the mutable Map class when I import it:

# at first i get an immutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

# i rename the mutable Map class when i import it
scala> import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{Map=>MMap}

# here i still get an immutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

# but here i get a mutable Map by referring to MMap
scala> val m = MMap("name" -> "Al")
m: scala.collection.mutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

I personally like this approach, because again it makes the code more obvious. You could correctly argue that I could have made it even more obvious if I renamed the class to MutableMap, but in this case I opted for brevity.

Summary

There are many more ways you can use this ability to rename classes when you import them in Scala, and if you have a good example you'd like to share, just leave a note below. Until then, reporting live from Boulder, Colorado, this is Alvin Alexander.

Posted by 1010
00.scala2014. 3. 28. 13:04
반응형

In Java, you sometimes refer to .class in your source code, like this:

info = new DataLine.Info(TargetDataLine.class, null);

As you can see, I refer to TargetDataLine.class in this code. This works fine in Java, but if you've tried it in Scala, you know the .class part of that code won't work.

In Scala, if you want to use ".class", you instead need to use the classOf function: The following Scala classOf code is equivalent to the previous Java .class code:

val info = new DataLine.Info(classOf[TargetDataLine], null)

In summary:

In Java, use Foo.class
In Scala, use classOf[Foo]

Scala getClass and classOf

I won't take any time to discuss this today, but if you're interested in a little more information, here's the output from a short Scala REPL session that shows how to use getClass and classOf:

scala> val s = "Foo"
s: java.lang.String = Foo

scala> s.getClass
res7: java.lang.Class[_ <: java.lang.String] = class java.lang.String

scala> s.getClass.toString
res8: java.lang.String = class java.lang.String

scala> classOf[String]
res9: java.lang.Class[String] = class java.lang.String


Posted by 1010