So I decided to pick up the Scala language. Having done Ruby for a couple of years now Scala is one of the few, if not the only language that’s gotten me excited. Being a first class citizen on the JVM has many advantages and I’m really liking LiftWeb.
I also suspect I’ll be doing a bit more Java related stuff in the very near future (stay tuned for that one
) so it’s a good idea to dive into the J world again, and what better way then with Scala!
Problem definition: there is an issue with some XML files which came with a large batch ingest for one of our clients. In short there are a bunch of track elements in the XML which each element having a on_disc and sequence_number (think audio CDs) . However, the sequence_numbers should always be incremented e.g. if you have 2 tracks on disc 1 and 3 tracks on disc 2 the tracks on disc 2 should be have sequence numbers 3,4 and 5 respectively. The XML files we got have reset the sequence_number to 1 whenever a new disc begins.The fix is thus a simple matter of adding the highest sequence number of the previous disc to the sequence number of the current disc. Easy enough.
I tried to implement this in Scala and one of the helper methods calculates the highest sequence number of a given disc. This is the odd part though
// The XML is first parsed to read all tracks
// These are stored in a tuple list
// Note the order of the tuples!
// Tuple values are (on_volume, sequence_number)
val sequence = List((1,2),(1,1),(2,1),(2,2),(2,3))
// Find the max value given a volume
def maxVal(vol: Int): Int = {
var max = 1
for (t <- sequence
if t._1 == vol;
if t._2 > max) max = t._2
max
}
println(maxVal(1))
Now my Ruby brain would expect this to print out 2, however when you run this code the result will be 1! That’s because the filters are actually creating a new list before feeding that to for clause so max is always 1 in the test. I did not expect this
You could use a left fold (similar to inject in ruby) to avoid the forloop:
def findMax(list:List[(Int,Int)], comp:Int) = {
list.foldLeft(0){(s,v) => if(v._1 == comp && v._2 > s) v._2 else s}
}
Kewl!!
Pingback: Scala scripting continued « LoLoCoJr