Scala Map의 키와 값 모두 매핑


89

스칼라의 MapLike특성에는 방법이 있습니다.

mapValues [C] (f: (B) ⇒ C): Map[A, C] 

하지만 때로는 다른 유형을 원합니다.

mapKeysAndValues [C] (f: (A, B) ⇒ C): Map[A, C] 

내가 놓친 간단한 방법이 있습니까? 물론 이것은 접어서 할 수 있습니다.

답변:


166

map메소드는 모든 (key, value)쌍을 반복합니다 . 다음과 같이 사용할 수 있습니다.

val m = Map("a" -> 1, "b" -> 2)

val incM = m map {case (key, value) => (key, value + 1)}

8
이미 기능이있는 경우 f : (A,B) => (A,C)간단하게 할 수 있습니다 m.map(f.tupled). 와 함께 작동 val f = (x: String, y: Int) => (x, y+1)하지만 이상하게도 내가 f동등하게 정의하면 repl이 불평합니다 def.
Dan Burton 2012

2
case여기서 키워드는 무엇을 달성합니까?
Omnipresent

{case (key, value) => ...}이 경우 @Omnipresent 는 패턴 일치 일뿐 입니다. 에 함수를 제공하는 대신 map부분 함수를 제공합니다.
tenshi

참고 : case패턴에 유형을 넣을 수는 있지만 런타임 오류를 생성 할 수 있으므로 안전하지 않습니다 (패턴 일치 일 뿐이 기 때문). 한편 map으로 해석 할 개체가 너무 적거나 너무 많아서 함수 아래에있는 컬렉션의 구조를 변경 (key, value)한 경우 다시 한 번 런타임 오류가 발생할 것으로 예상합니다. :(
combinatorist

8

이 코드는 어떻습니까?

val m = Map(1 -> "one", 2 -> "two")
def f(k: Int, v: String) = k + "-" + v
m map {case (k, v) => (k, f(k, v))}

다음을 생성합니다.

 Map(1 -> 1-one, 2 -> 2-two)

이것은 유틸리티 방법으로 패키징 될 수 있습니다 :

def mapKeysAndValues[A,B,C](input: Map[A,B], fun: (A, B) => C) = 
  input map {case(k,v) => (k, fun(k, v))}

용법:

mapKeysAndValues(
  Map(1 -> "one", 2 -> "two"), 
  (k: Int, v: String) => k + "-" + v
)

이것과 같지 MapLike#transform않습니까?
Hosam Aly


2

일부 Scalaz 사용 :

scala> def fst[A, B] = (x: (A, B)) => x._1
fst: [A, B]=> (A, B) => A

scala> Map(1 -> "Lorem", 2 -> "Ipsum").map(fst &&& Function.tupled(_.toString + _))
res1: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> 1Lorem, 2 -> 2Ipsum)

@tenshi의 솔루션이 더 좋습니다.


0

유틸리티 클래스를 만들 수 있습니다.

class MyMapLike[K,V](m:MapLike[K,V,_]){
 def mapKeysAndValues[R](f: (K, V) => R)={
   m.map{case (k,v)=> f(k,v)}
 } 
}
object MyMapLike{
 implicit def maplike2mymaplike[K,V](ml:MapLike[K,V,_]):MyMapLike[K,V]=new MyMapLike(m)

}

import MyMapLike._
Map(1 -> "one", 2 -> "two").mapKeysAndValues(k,v=>v*k)

코드는 테스트되지 않았지만 어떻게 든 비슷하게 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.