1

我有以下类型的结果 Map 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"
    ]]

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

4

4 回答 4

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 }
于 2012-08-14T19:34:09.550 回答
2

您可以在您的理解中使用多个生成器(如果也可以使用):

val test = (for {
  (time, m) <- ret
  (k,v) <- m
  if v == "Ry7H5_client"
} yield Seq(time, v)).toList
于 2012-08-14T20:01:17.707 回答
0

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

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))
于 2012-08-14T19:58:01.893 回答
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))

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

于 2012-08-14T20:10:47.413 回答