9

我正在尝试转换List("a,1" , "b,2" , "c,3" , "a,2" , "b,4")scala.collection.immutable.HashMap[String, java.util.List[String]]带值的类型:

a -> 1,2
b -> 2,4
c -> 3

所以每个键都包含一个其值的列表。

到目前为止,这是我的代码:

object ConvertList extends Application {

  var details = new scala.collection.immutable.HashMap[String, java.util.List[String]]

  val strList = List("a,1" , "b,2" , "c,3" , "a,2" , "b,4")

  //Get all values
  val getValue : Function1[String, String] = { a => a.split(",")(1) }
  val allValues : List[String] = strList map getValue

  //get unique values
  val uniqueValues = allValues.toSet[String]

  //Somehow map each unique value to a value in the original List....
  println(uniqueValues)

  println(strList.flatten)
  //userDetails += "1" -> List("a","b",


}

如何执行此转换?

4

5 回答 5

14
strList.map(s => (s(0).toString,s(2).toString))
       .groupBy(_._1)
       .mapValues(_.map(_._2))

输出 :

Map[String,List[String]] = Map(b -> List(2, 4), a -> List(1, 2), c -> List(3))
于 2013-08-29T20:58:55.740 回答
3

列表的顺序不会相同,但通常这是非常可行的问题:

// for a sake of pithiness
type M = Map[String,List[String]] 
def empty: M = Map.empty.withDefaultValue(Nil)

@annotation.tailrec
def group(xs: List[String], m: M = empty): M = xs match {
    case Nil     => m
    case h::tail => 
      val Array(k,v) = h.split(",")
      val updated = v::m(k)
      combine(tail, m + (k -> updated))
}
于 2013-08-29T20:58:08.953 回答
3

已经有很多镜头了,但是类似于 Marth 提议的东西呢:

import scala.collection.JavaConverters._

val strList = List("a,1" , "b,2" , "c,3" , "a,2" , "b,4")

strList.map(_.split(',')).collect { 
  case Array(key, value) => key -> value 
}.groupBy(_._1).mapValues(_.map(_._2).asJava)

这在很大程度上依赖于函数式编程并以 aMap类型结束Map[String, java.util.List[String]],同时不仅在输入字符串中占据固定位置,而且在逗号处分割(想象有超过 9 的数字,需要不止一个数字)。

此外,如果拆分中有多个值,该collect方法会将它们过滤掉。

于 2013-08-29T21:08:44.810 回答
1
scala> List("a,1" , "b,2" , "c,3" , "a,2" , "b,4")
res0: List[String] = List(a,1, b,2, c,3, a,2, b,4)

scala> res0.groupBy(xs => xs.split(",")(0)).mapValues(xs => xs.flatMap(xs => xs.toCharArray.filter(_.isDigit)))
res2: scala.collection.immutable.Map[String,List[Char]] = Map(b -> List(2, 4), a -> List(1, 2), c -> List(3))

由于groupBy您想要一个Map. groupBy拆分Listby的每个元素,并取第一个作为键的元素。这给出了这个: scala.collection.immutable.Map[String,List[String]] = Map(b -> List(b,2, b,4), a -> List(a,1, a,2), c -> List(c,3))。从这里开始,它只是处理从每个List值中获取数字。

这会返回一个Map[String, List[Char]]. 如果您想退货,还有更多工作要做,scala.collection.immutable.HashMap[String, java.util.List[String]]但这很容易。

于 2013-08-29T20:58:16.447 回答
0

开始Scala 2.13,我们可以使用新的groupMap方法(顾名思义),它相当于 agroupBymapping 分组项:

// val strList = List("a,1" , "b,2" , "c,3" , "a,2" , "b,4")
strList.map(_.split(",")).groupMap(_(0))(_(1))
// Map("b" -> List(2, 4), "a" -> List(1, 2), "c" -> List(3))

这个:

  • 拆分每个字符串(生成List(Array(a, 1), Array(b, 2), ...)

  • groups 元素基于它们的第一部分 ( _(0))(Map 的组部分)

  • maps 分组元素到它们的第二部分(_(1))(组Map的映射部分)

于 2019-02-16T22:48:44.367 回答