Scala Map的迭代和过滤

时间:2012-08-14 19:20:15

标签: scala

我有以下结果类型为Map[Long,Map[String,String]]的Map。我想将地图转换为List[Seq[Long,String]]

以下代码做得很好:

val test = for((time, m) <- ret) yield for((k, v) <- m) yield Seq(time, v)

问题是我实际上只想包含Seq(time, v) v唯一的 [[ 1344969305196000, "Ry7H5_client" ], [ 1344969777610000, "Ry7H5_client" ], [ 1344965964890000, "SOCKET/f6KGcMSVi7" ], [ 1344969919131000, "Ry7H5_client" ]] 。例如,目前我得到以下值:

{{1}}

我想在结果集中只包含一次“Ry7H5_client”。什么是最好的解决方法?

4 个答案:

答案 0 :(得分:2)

您可以确定要删除的键,例如

val res = Map(1 -> 2, 3 -> 2, 4 -> 1)

val keysToDelete = res.groupBy(_._2).collect { case (_, m) if m.size > 1 => m.keys }.flatten
// keysToDelete: scala.collection.immutable.Iterable[Int] = List(1, 3)

val resultMap = res -- keysToDelete
// resultMap: scala.collection.immutable.Map[Int,Int] = Map(4 -> 1)

编辑:

收集所有值的键,其中包含您可以执行的短语

Map(1 -> "FOO_SOCKET_BAR", 2 -> "FOO_BAR").collect { case (key,value) if value.contains("SOCKET") => key }

为了提高效率,您还可以在此处使用已编译的正则表达式:

val regex = ".*SOCKET.*".r
Map(1 -> "FOO_SOCKET_BAR", 2 -> "FOO_BAR").collect { case (key,regex()) => key }

答案 1 :(得分:2)

你可以在for-comprehension中使用多个生成器(如果也可以使用的话):

val test = (for {
  (time, m) <- ret
  (k,v) <- m
  if v == "Ry7H5_client"
} yield Seq(time, v)).toList

答案 2 :(得分:0)

只需将字符串分组,然后映射到每个组的头部:

scala> val list = List((1344969305196000L, "Ry7H5_client"), (1344969777610000L,  
"Ry7H5_client"), (1344965964890000L,"SOCKET/f6KGcMSVi7"), (1344969919131000L, "R 
y7H5_client"))
list: List[(Long, java.lang.String)] = List((1344969305196000,Ry7H5_client), 
(1344969777610000,Ry7H5_client), (1344965964890000,SOCKET/f6KGcMSVi7), 
(1344969919131000,Ry7H5_client))

scala> list.groupBy(x => x._2).map((e) =>  e._2.head).toList
res0: List[(Long, java.lang.String)] = List((1344965964890000,SOCKET/f6KGcMSVi7),
(1344969305196000,Ry7H5_client))

答案 3 :(得分:0)

这个怎么样

object SO extends App {

  val ret = Map(
    1344969305196000L -> Map("a" -> "Ry7H5_client"),
    1344969777610000L -> Map("a" -> "Ry7H5_client"),
    1344965964890000L -> Map("a" -> "SOCKET/f6KGcMSVi7"),
    1344969919131000L -> Map("a" -> "Ry7H5_client"))

  val test2 = for {
    (m, time) <- ret.map(_.swap)
    (k, v) <- m
  } yield Seq(time, v)

  println(test2)
}

给出清单(清单(1344969919131000,Ry7H5_client),清单(1344965964890000,SOCKET / f6KGcMSVi7))

PS。地图中的“a”只是为了使类型与原始问题相匹配,看起来并不重要。