我正在尝试将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",
}
如何执行此转换?
答案 0 :(得分:13)
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))
答案 1 :(得分: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))
}
答案 2 :(得分: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)
这很大程度上依赖于函数式编程,最终得到Map
类型Map[String, java.util.List[String]]
,而不只是在输入字符串中占用固定位置,而是在逗号处分割(想象数字超过9,需要多个数字。)
此外,如果拆分中有多个值,collect
方法会将其过滤掉。
答案 3 :(得分: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
将List
的每个元素拆分为,
,并取第一个作为关键字的元素。这给了这个:
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]]
返回,还有一些事要做,但这很容易。
答案 4 :(得分:0)
从Scala 2.13
开始,我们可以使用新的groupMap方法(顾名思义),它等效于groupBy
和map
分组的项目:
// 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), ...)
)
group
的元素基于其第一部分(_(0)
)(组地图的组部分)
map
的元素分组到第二部分(_(1)
)(组 Map 的映射部分)