Alex Alex - 4 years ago 119
Scala Question

Assigning ordinal numeral to sequence without post-decrement in scala

As I'm new to scala I google many things and find good answers in most cases. But I couldn't find an answer to this specific question as googling "post-decrement in scala" only brings dontcha-use-post-decrement-in-scala-because-its-a-functional-language-answers to the top.

So, I really want to know what's the functional way of doing the following:

object A {
val list = List("a", "b", "c")
val map = {
var ord = list.size
Map(list map { x => (x, { val res = ord; ord -= 1; res } ) } : _* )
}
}

class Test extends org.scalatest.FunSuite {
test("") {
println(A.map) // Map(a -> 3, b -> 2, c -> 1)
}
}


It's basically creating a map from a given list and assigning decreasing ordinal numerals to each element of the list (real code is of course more complex than this minimal example).

I'm especially unhappy with
var ord = ...
(mutable) and
{ val res = ord; ord -= 1; res }
(post-decrement) parts :/ Is there another (prettier) way of doing this?

Answer Source

A quick solution would require reversing the list and then you can use zipWithIndex:

scala> :pa
// Entering paste mode (ctrl-D to finish)

List("a", "b", "c")
  .reverse
  .zipWithIndex
  .toMap

// Exiting paste mode, now interpreting.

res4: scala.collection.immutable.Map[String,Int] = Map(c -> 0, b -> 1, a -> 2)

If you don't mind the allocations of the extra collections, you can remove view.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download