1

我有一个List(List("aba, 4"), List("baa, 2")),我想把它转换成一张地图:

val map : Map[String, Int] = Map("aba" -> 4, "baa" -> 2)

归档这个的最好方法是什么?

更新:

我进行数据库查询以检索数据: val (_, myData) = DB.runQuery(...)

这会返回一对,但我只对第二部分感兴趣,这给了我:

myData: List[List[String]] = List(List(Hello, 19), List(World, 14), List(Foo, 13), List(Bar, 13), List(Bar, 12), List(Baz, 12), List(Baz, 11), ...)
4

4 回答 4

8
scala> val pat = """\((.*),\s*(.*)\)""".r
pat: scala.util.matching.Regex = \((.*),\s*(.*)\)

scala> list.flatten.map{case pat(k, v) => k -> v.toInt }.toMap
res1: scala.collection.immutable.Map[String,Int] = Map(aba -> 4, baa -> 2)
于 2012-04-08T13:42:38.537 回答
4

另一个采取:

List(List("aba, 4"), List("baa, 2")).
  flatten.par.collect(
    _.split(",").toList match {
      case k :: v :: Nil => (k, v.trim.toInt) 
  }).toMap

与其他答案的区别:

  • 用于.par并行创建对,这使我们能够从多个内核中获利。
  • collect与 a一起使用PartialFunction以忽略不属于“key, value”形式的字符串

编辑:.par不会破坏之前作为答案状态的订单。只有列表处理的执行顺序不能保证,所以函数应该没有副作用(或者副作用不应该关心排序)。

于 2012-04-08T13:01:02.097 回答
1

我的看法:

List(List("aba, 4"), List("baa, 2")) map {_.head} map {itemList => itemList split ",\\s*"} map {itemArr => (itemArr(0), itemArr(1).toInt)} toMap

在步骤:

List(List("aba, 4"), List("baa, 2")).
  map(_.head).                                    //List("aba, 4", "baa, 2")
  map(itemList => itemList split ",\\s*").        //List(Array("aba", "4"), Array("baa", "2"))
  map(itemArr => (itemArr(0), itemArr(1).toInt)). //List(("aba", 4), ("baa", 2))
  toMap                                           //Map("aba" -> 4, "baa" -> 2)

您的输入数据结构有点尴尬,所以我认为您无法进一步优化/缩短它。

于 2012-04-08T11:26:32.190 回答
1
List(List("aba, 4"), List("baa, 2")).
  flatten.     //get rid of those weird inner Lists
  map {s=> 
    //split into key and value
    //Array extractor guarantees we get exactly 2 matches
    val Array(k,v) = s.split(","); 
    //make a tuple out of the splits
    (k, v.trim.toInt)}.
  toMap  // turns an collection of tuples into a map
于 2012-04-08T12:27:59.900 回答