Scala - 如何定义地图,其中值取决于密钥?

Dmi*_*kov 7 dictionary scala

有没有办法定义一个Map,其中Map值取决于它的键,比如

Map(key -> f(key), key2 -> f(key2), ...).
Run Code Online (Sandbox Code Playgroud)

Kev*_*ght 11

你正在以错误的方式看待这个......

A Map[K,V]也是一个例子Partialfunction[K,V].因此,改变你使用你的Map类型(vals,方法参数等)的所有地方PartialFunction.

然后,您可以f直接使用,或者Map[K,V]在键和值之间没有简单代数关系的地方提供实例.

例如

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)
Run Code Online (Sandbox Code Playgroud)

您也可能还想考虑使用(K) => Option[V],在这种情况下,您可以通过lift方法提供类型的实例,该方法映射继承自PartialFunction

例如

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)))
Run Code Online (Sandbox Code Playgroud)


Sar*_*ngh 6

假设您将密钥放在这样的列表中,并且您希望将其转换为正方形作为值.

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)
Run Code Online (Sandbox Code Playgroud)

或者在一行中完成

( 1 to 10 ).toList.map( x => ( x, x * x ) ).toMap
Run Code Online (Sandbox Code Playgroud)

或者......如果您只有几个键......那么您可以编写特定的代码

Map( 1 -> doSquare( 1 ), 2 -> doSquare( 2 ) )
Run Code Online (Sandbox Code Playgroud)