Reputation: 2908
I have the following result Map that has the type Map[Long,Map[String,String]]
. I would like to convert the Map to a List[Seq[Long,String]]
.
The following code does this well:
val test = for((time, m) <- ret) yield for((k, v) <- m) yield Seq(time, v)
The issue is I actually only want to include the Seq(time, v)
where v
is unique. For example, currently I get the following values:
[[
1344969305196000,
"Ry7H5_client"
],
[
1344969777610000,
"Ry7H5_client"
],
[
1344965964890000,
"SOCKET/f6KGcMSVi7"
],
[
1344969919131000,
"Ry7H5_client"
]]
I would like to only include the "Ry7H5_client" once in my result set. What would be the best way of going about this?
Upvotes: 1
Views: 272
Reputation: 24413
You can determine the keys to delete with sth like
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)
edit:
to collect the keys for all values, that contain a phrase you can do
Map(1 -> "FOO_SOCKET_BAR", 2 -> "FOO_BAR").collect { case (key,value) if value.contains("SOCKET") => key }
and to be more efficient, you could also use a compiled regex here:
val regex = ".*SOCKET.*".r
Map(1 -> "FOO_SOCKET_BAR", 2 -> "FOO_BAR").collect { case (key,regex()) => key }
Upvotes: 2
Reputation: 3608
You can use multiple generators in your for-comprehension (if might be used as well):
val test = (for {
(time, m) <- ret
(k,v) <- m
if v == "Ry7H5_client"
} yield Seq(time, v)).toList
Upvotes: 2
Reputation: 21081
Just groupBy the Strings and then map to the head of each group:
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))
Upvotes: 0
Reputation: 4007
How about this
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)
}
Gives List(List(1344969919131000, Ry7H5_client), List(1344965964890000, SOCKET/f6KGcMSVi7))
ps. the "a" in the Map is just to make the types match your original problem, it looks like its not important.
Upvotes: 0