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