Preface
Goal: Continue Part One.
Scala
is powerful,
but I guess my previous case example is not complex enough.
We cannot just jump to this intermediate topic,
with lack of basic code introduction,
I need to explore scala
more, and get more interesting experience.
So I dedicate this article to cover basic scala
trick.
4: Alternate Approach
Since our introduction to scala
above is too short,
consider to makes it more complete
alternate flatten written in imperative fashioned.
Then we are going to continue with recursive example,
and also, with head and tail x:xs
pattern,
until finally conclude with our songs task with alternate solution.
For Loop Using yield
We are going to use for loop. Consider start from a very simple example.
object T09f extends App {
def loop(tags: List[String])
= for (tag <- tags) yield tag
val tags: List[String] =
List("rock", "jazz", "rock", "pop", "pop")
println(loop(tags))
}
With the result similar as below:
$ scala T09For.scala
List(rock, jazz, rock, pop, pop)
Custom Flatten Using yield
Not every real life code is functional.
Some case such as concurrency are naturally comes from side effect.
Thus we need to prepare to handle this,
without map
, filter
, or reduce
.
We can write our custom flatten using for loop.
import mysongs._
import mysongs.MySongs._
object T09 extends App {
def songsFlatten(songs: List[Song])
= for (
song <- songs if song.tags != None;
tag <- song.tags.get
) yield tag
println(songsFlatten(songs))
}
With the result similar as below string
:
$ scala T09Flatten.scala
List(60s, jazz, 60s, rock, 70s, rock, 70s, pop)
Exclude with Filter
Head and tail pattern matching is made of two functions:
- Exclude
- Unique
We can write the exclude
function to this below:
object T10 extends App {
def exclude(value: String, tags: List[String])
: List[String]
= tags filter (tag => {tag!=value})
val tags: List[String] =
List("rock", "jazz", "rock", "pop", "pop")
println(exclude("rock", tags))
}
With the result similar as below list
:
$ scala T10Exclude.scala
List(jazz, pop, pop)
Unique with Pattern Matching
And the unique
is recursive function,
with head and tail pattern matching.
object T11 extends App {
def exclude(value: String, tags: List[String])
: List[String]
= tags filter (tag => {tag!=value})
def unique(tags: List[String])
: List[String]
= tags match {
case Nil => List()
case x::Nil => List(x)
case x::xs => x::unique(exclude(x, xs))
}
val tags: List[String] =
List("rock", "jazz", "rock", "pop", "pop")
println(unique(tags))
}
With the result similar as below list
:
$ scala T11Unique.scala
List(rock, jazz, pop)
I guess the code itself is self explanatory.
Put All The String Together
We can apply all to finish our previous songs task, with entirely different approach.
import mysongs._
import mysongs.MySongs._
object T12 extends App {
def songsFlatten(songs: List[Song])
= for (
song <- songs if song.tags != None;
tag <- song.tags.get
) yield tag
def exclude(value: String, tags: List[String])
: List[String]
= tags filter (tag => {tag!=value})
def unique(tags: List[String])
: List[String]
= tags match {
case Nil => List()
case x::Nil => List(x)
case x::xs => x::unique(exclude(x, xs))
}
println(unique(songsFlatten(songs)))
}
With the result similar as below list
:
$ scala T12Songs.scala
List(60s, jazz, rock, 70s, pop)
We should be ready for our next topic,
concurrency case example in Scala
.
In other time, other article.
What is Next 🤔?
Meanwhile, you can learn Lua
.
Consider continue reading [ Lua - Playing with Records - Part One ].