Iterating over a sequence

Scala fits pretty well with list manipulations. Indeed, it facilitates their usage by defining a lot of methods that enable a lot of behaviors, such as filtering elements or grouping them based on an aggregation value. There are tons of such methods, and actually, if we need something to do something with a sequence, it should already be defined at http://www.scala-lang.org/api/current/index.html#scala.collection.Seq.

In the coming sections, we'll cover the most useful sequences when building Scala templates. First of all, let me just point to the fact that in Scala, when we think List we mean Seq.

Function – foreach

The foreach method provides a way to iterate over a sequence and apply a given function to each item. In object-oriented programming, we can think of it as a visitor pattern on a flat list.

The result of foreach is Unit, which is the Scala version of void in Java.

The following screenshot shows how to use it:

Function – foreach

As we can see, the Java code is less elegant and requires "boilerplate" (a Function0 implementation), but it explains well what the Scala code does.

Note

In Scala, we didn't declare the data type to be Int due to type inference. Type inference stands for the mechanism that allows a compiler to discover what the type of a variable is.

Function – map

The map method is pretty much like the foreach method, but instead of returning Unit, map returns a new sequence composed of the results of the function applied to each element. So it provides a way to adapt each element, while keeping them arranged in a sequence.

The following screenshot shows how to use it:

Function – map

Here again, the Java version is more verbose, but reading the code would help you to understand the Scala version better than if it was explained in words

Note

In the Scala version, we can see another use of the underscore (_) character. Here it represents a placeholder for the current function's argument. It's the more concise way to define inline functions. In this case, it is the same as having (x:Int)=>math.pow(2, x).

Function – filter

The name of this function is self-descriptive; it allows us to iterate over a sequence by applying a given predicate on each item, and returns a sequence of all the valid elements.

Let's jump into the code directly:

Function – filter

So short and so helpful, isn't it?

The code is pretty straightforward and self-descriptive. We ask the seq sequence to be filtered using a predicate function that tests if the integer is even. So the result will be a new sequence of all the even elements in seq.

Function – exists

This exists method is like contains in Java, but it uses a comparison function rather than using equals.

The following screenshot shows how to make use of it:

Function – exists

It's that simple!

Note

Looking closer at the example, you'll see that the Scala version doesn't use dots to separate the method from the caller; that's the point-less notation . This feature could also be called the distraction-zero notation , which is a welcome feature when creating a DSL.

Function – find

One of the common tasks with sequences is to retrieve an item that must match a predicate. Scala has the find method for that, and it has a specific behavior when none of the elements match.

This method will iterate over the sequence by checking the predicate and return an Option[El] value in all cases. An Option is a special type in Scala that is meant to represent a value or non-value; it is explained as follows:

  • object None extends Option[Nothing]: This extension of Option simply represents a non-value. It'll be returned if no element has been found.
  • case class Some[El](v:El) extends Option[El]: This extension of Option represents a wrapper over a value (v).

This type enforces the definition of a variable to be potentially undefined. We can also think of None as a type-safe null in Java, and it can be used as an alternative to exceptions. Indeed, if we have a function that parses String as Int, it could return an Option of type Int rather than an Int type, so the user will be able to react to bad strings rather than catching the exception.

It's time to see it in action:

Function – find

As the Option structure is not available in Java, we had to define it (in some way) in order to mimic as much as possible of the Scala code.

Note

Java 8 has introduced a new type called java.util.Optional that does much the same. But it would have been cumbersome to implement our example with Java 8.

Function – apply

The last method we'll see in this section is the apply method. The Scala compiler has a special behavior for the apply method because it's not mandatory to call it explicitly.

Indeed, when a type declares an apply method, we'll be able to call its instances as if they were functions. See the following screenshot for an example of this:

Function – apply

What is shown in the previous screenshot is an example of how we can create a template that has been rendered by giving a file and a list of arguments. It has a render method that renders the file using the given parameters, which is called within the apply method. As the goal of Renderer is to create a usable representation of a template, it seems obvious that we should be able to call this task easily and in a readable manner. This is what is achieved in the two last statements.

Note

arguments: Any* is the Scala way to declare a varargs Object... argument, Any being Java's Object.

Going back to the sequences, we can now imagine what the apply method of a sequence would be, given that it takes an Int type—it's the index of the requested element.

Function – apply

Other interesting functions

Sequences (iterables) define plenty of methods that are very useful and, truly, cover every use case that we'll encounter while dealing with them.

Following are some other functions that you might want to have a look at some time:

  • partition: Based on a predicate, this function splits the sequence in two
  • collect: This function mixes map and filter at once
  • groupBy: It takes a function that must produce the key values of a resulting map that packages all elements having the same key value
  • sliding: This packages the elements using a window and slides it over the whole sequence (it is graceful in dealing with items that need to be shown in a predefined number of columns, for example, a gallery)
  • length: This returns the number of items in the sequence
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset