Reputation: 4699
I am trying to find a key in a Map, given a value. I am using the 'find' function by not able to figure out the right predicate for it:
val colors = Map(1 -> "red", 2 -> "blue")
def keyForValue(map: Map[Int, String], value: String) = {
val bool = map.find{map.foreach{map.values(i) == value}}
bool.key
}
How do I iterate over the map and find the key when I know the value?
Upvotes: 15
Views: 24242
Reputation: 2105
I would avoid passing the map to the find method, and rather pass only the map's keys to the find method.
This avoids dealing with an Option[Int,String] -- instead it is Option[Int].
// sample data
val colors = Map(1 -> "red", 2 -> "blue", 3 -> "yellow")
// function you need
def keyForValue(theMap: Map[Int, String], theValue: String): Int = {
val someKey = theMap.keys.find( k => theMap(k) == theValue )
someKey match {
case Some(key) => {
println(s"the map contains ${key} -> ${theValue}")
return key
}
case None => {
println(s"a key was not found for ${theValue}")
return -1
}
}
}
This gives:
scala> val result = keyForValue( colors, "blue" )
the map contains 2 -> blue
result: Int = 2
scala>
Upvotes: 0
Reputation: 23
You can always go with the abstract solution and swap the keys with their values, store it in a new map, and then search the new map:
val colors = Map(1 -> "red", 2 -> "blue")
def keyForValue(map: Map[Int, String], value: String) = {
val revMap = map map {_.swap}
val key = revMap(value)
key
}
The third line swaps the keys with their values, and stores it in revMap
. (map map
means the name of the map, in this case, the parameter, map, then the word map, then {_.swap}
to actually swap the keys with their values.
Upvotes: 1
Reputation: 9705
You use the same kind of predicate as with a List
, but keep in mind you're evaluating it over (key,value)
pairs, instead of just values (and getting a pair back as well!).
Simple example:
val default = (-1,"")
val value = "red"
colors.find(_._2==value).getOrElse(default)._1
Upvotes: 20
Reputation: 20285
The signature for find
in Map
is find(p: ((A, B)) ⇒ Boolean): Option[(A, B)]
. So the predicate takes a Tuple2
and must return a Boolean
. Note I changed value
to an Int
since the key in colors
is also an Int
.
scala> def keyForValue(map: Map[Int, String], value: Int) = {
| colors.find({case (a,b) => a == value})
| }
keyForValue: (map: Map[Int,String], value: Int)Option[(Int, String)]
Test:
scala> keyForValue(colors, 1)
res0: Option[(Int, String)] = Some((1,red))
You can also use get
:
scala> colors.get(1)
res1: Option[String] = Some(red)
Upvotes: 2