First stab at Scala scripting.. filters do not work like my Ruby brain thinks they do

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 :-)

This entry was posted in scala and tagged . Bookmark the permalink.

3 Responses to First stab at Scala scripting.. filters do not work like my Ruby brain thinks they do

  1. p3t0r says:

    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}
    }

  2. Pingback: Scala scripting continued « LoLoCoJr

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>