0

I need to pass multiple arguments into a scala program from the command line. The first one is the database, the second one is the table and the third one needs to be a map where the Map can have from 1 to n combinations of (String, Int). My script would then be executed like this:

$ scala script.scala dbame tablename Map(("score100", 20), ("score200", 10))

How do I pass that Map to the fields variable in my script (see code below)?

val database = args.length match {                                               
  case x:Int if x>0 => args(0)
  case _ => {
    println("error") 
    System.exit(1)
  }
}

val table = args.length match {
  case x:Int if x>1 => args(1)
  case _ => {
    println("error") 
    System.exit(1)
  }
}

val fields = args.length match {
  case x:Int if x>2 => args(2)
  case _ => {
    println("error") 
    System.exit(1)
  }
}
nickfrenchy
  • 293
  • 4
  • 16
  • It is possible like this : https://stackoverflow.com/questions/367706/how-to-parse-command-line-arguments-in-java – tharindu_DG Jun 17 '17 at 12:32

1 Answers1

2

Just pass them as a flat list of arguments:

scala script.scala dbame tablename score100 20 score 200 10 ...

Then you can do something like this:

val (dbname, tablename, params) = args match {
   case Seq(dbname, tablename, params@_*) => 
      (dbname, tablename, params.grouped(2).map(p => p.head -> p.last).toMap)
   case _ => throw new IllegalArgumentException("dbname and tablename must be given)
}
Dima
  • 39,570
  • 6
  • 44
  • 70
  • I had to change Seq to Array for it to work. Works great. – nickfrenchy Jun 17 '17 at 16:39
  • It seems if I pass the same argument key with different values, the key is updated. scala script.scala dbname tablename score1 10 score2 10 score1 20 will return score1 20 and score2 10. I need to keep all three. – nickfrenchy Jun 18 '17 at 08:18
  • Then you can't use a map for that. Map can only have have one of each key. Or you can make it a `Map[String, Seq[String]]`, mapping each key to a collection of values rather than a single value: `params.grouped(2).map(p => p.head -> p.last).groupBy(_._1).mapValues(_.map(_._2))` – Dima Jun 18 '17 at 12:45
  • This works. I had to add `.toVector` before the `.groupBy` to avoid an error. – nickfrenchy Jun 18 '17 at 17:55