如何使元素包含'$'字符作为键,并在键的数字后面作为列表?

mop*_*mop 2 scala

有一个数组,如何使元素包含'$'字符作为键,并在键的数字后面作为List

val a = Array("$A", 1234, "$B", 123, 4, 5)
Run Code Online (Sandbox Code Playgroud)

预期:

Map("$A"->List(1234),"$B"->List(123,4,5)))
Run Code Online (Sandbox Code Playgroud)

所有回答者的thx,如下是我的最终代码:

a.toList.tails.collect {
  case (key: String) :: rest if key.contains('$') => (key, rest.takeWhile(!_.toString.contains('$')))
}.toMap
Run Code Online (Sandbox Code Playgroud)

dk1*_*k14 5

你可以这样做foldLeft(假设Array[Any]作为输入):

a.foldLeft(List.empty[(String, List[Int])]){
    case (acc, el: String) if el.head == '$' => 
      (el -> List.empty[Int]) :: acc 
    case (acc, el) => 
      val updatedHead = acc.head._1 -> (Integer.parseInt(el.toString) :: acc.head._2)
      updatedHead :: acc.tail
}.toMap.mapValues(_.reverse)
Run Code Online (Sandbox Code Playgroud)

reverse需要因为::(将元素添加到List的开头)比将元素添加到结尾更快,但是以List[Int]这种方式反转.

另一种选择是尾递归调用span.

PS小心,Map不保证插入顺序(即使是键,无论它是迭代器),所以你不能将它用于累加器(你不能从中获取keys.last元素):

scala> (1 to 10).toList.foldLeft(Map.empty[Int, Int]){case (acc, x) => acc + (x -> x)}.keys.toList
res23: List[Int] = List(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)
Run Code Online (Sandbox Code Playgroud)

但是,您可以使用ListMap,但keys.lastlist.head(恒定时间)慢(线性时间).

PS2请记住,您的a.toList.tails.collect...版本会重新访问某些元素2-3次:当collect跳过整数时,1次额外的时间,当takeWhile检测到序列结束时另外1次,因此可能会影响性能.