Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 将字符串列表转换为映射[字符串,列表]_Scala - Fatal编程技术网

Scala 将字符串列表转换为映射[字符串,列表]

Scala 将字符串列表转换为映射[字符串,列表],scala,Scala,我正在尝试将列表(“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.collecti

我正在尝试将
列表(“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",


}

如何执行此转换?

列表的顺序可能不同,但通常这是一个非常可行的问题:

// 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))
}
使用
groupBy
可以直接实现这一点,因为您需要
地图。
groupBy
拆分
列表中的每个元素,并获取第一个元素,即键。因此:
scala.collection.immutable.Map[String,List[String]=Map(b->List(b,2,b,4),a->List(a,1,a,2),c->List(c,3))
。从这里开始,它只是处理从每个
值列表中获取数字

这将返回一个
Map[String,List[Char]]
。如果希望
scala.collection.immutable.HashMap[String,java.util.List[String]]
返回,那么还有一些事情要做,但这是最简单的部分

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))

现在已经有了大量的尝试,但是类似于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[String,java.util.List[String]]
Map
,而不仅仅是在输入字符串中固定位置,而是在逗号处拆分(想象数字超过9,需要多个数字)


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

Scala 2.13
开始,我们可以使用新方法(顾名思义),它是一种一次性等效于
groupBy
map
ping分组项的方法:

// 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))
这:

  • 拆分每个字符串(生成
    列表(数组(a,1),数组(b,2),…)

  • 根据元素的第一部分(
    (0)
    )对元素进行分组(映射的分组部分)

  • map
    s将分组元素映射到它们的第二部分(
    (1)
    )(映射组的一部分map


你对不可变hashmap严格吗?@om nom nom不,我只是想避免一个强制性的解决方案。你能解释一下“s(0).toString,s(2).toString”吗?它是否将每个字符串元素映射到一个字符串、字符串元组?回答得很好。在字符串上建立索引确实使这个解决方案变得干净。向上投票。是的,它将每个字符串映射到这对夫妇(“第一个字母”、“第三个字母”)。(因此,“a,1”至(“a”,“1”))。您可以(而且应该说,这段代码不仅仅是一个脑筋急转弯)编写一个函数formatString,并使用strList.map(formatString.groupBy(…)更好地处理特殊情况(string.length<3,等等)
// 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))