Is there a way to define a Map, where Map value depends on its key, like
Map(key -> f(key), key2 -> f(key2), ...).
You're looking at this the wrong way...
A Map[K,V]
is also an instance of Partialfunction[K,V]
. So change everywhere you're using your Map
type (vals, method params, etc.) to be a PartialFunction
.
Then you can just work with f
directly, or supply a Map[K,V]
as the instance wherever you don't have a simple algebraic relationship between keys and values.
e.g.
def methodUsingMapping(x: PartialFunction[Int,Boolean]) = ...
//then
val myMap = Map(1->true, 2->true, 3->false)
methodUsingMapping(myMap)
//or
val isEven = PartialFunction(n: Int => n % 2 == 0)
methodUsingMapping(isEven)
//or
//note: case statements in a block is the smart way
// to define a partial function
// In this version, the result isn't even defined for odd numbers
val isEven: PartialFunction[Int,Boolean] = {
case n: Int if n % 2 == 0 => true
}
methodUsingMapping(isEven)
You also might also want to consider using (K) => Option[V]
, in which case you can supply an instance of the type via the lift
method, which maps inherit from PartialFunction
e.g.
def methodUsingMapping(x: (Int)=>Option[Boolean]) = ...
//then
val myMap = Map(1->true, 2->true, 3->false)
methodUsingMapping(myMap.lift)
//or
def isEven(n: Int) = Some(n % 2 == 0)
methodUsingMapping(isEven)
//or
def isEven(n: Int) = n % 2 == 0
methodUsingMapping(x => Some(isEven(x)))
Lets say you have your keys in a list like this, and you want to convert it map with squares as values.
scala> val keyList = ( 1 to 10 ).toList
keyList: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val doSquare = ( x: Int ) => x * x
doSquare: Int => Int = <function1>
// Convert it to the list of tuples - ( key, doSquare( key ) )
scala> val tupleList = keyList.map( key => ( key, doSquare( key ) ) )
tuple: List[(Int, Int)] = List((1,1), (2,4), (3,9), (4,16), (5,25), (6,36), (7,49), (8,64), (9,81), (10,100))
val keyMap = tuple.toMap
keyMap: scala.collection.immutable.Map[Int,Int] = Map(5 -> 25, 10 -> 100, 1 -> 1, 6 -> 36, 9 -> 81, 2 -> 4, 7 -> 49, 3 -> 9, 8 -> 64, 4 -> 16)
Or to do it in one line
( 1 to 10 ).toList.map( x => ( x, x * x ) ).toMap
Or... if you have just few keys... then you can write the specific code
Map( 1 -> doSquare( 1 ), 2 -> doSquare( 2 ) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With