이것은 this question과 유사합니다. 기본적으로 @serejja가 말했듯이 접근법은 정확하고 가장 간결합니다. 당신은 마지막 map
에 빌더 공장 인수로 collection.breakOut
사용하여 Set
유형 얻을 수있는 추가적인 반복을 절약 할 수있다 : 당신이 정말로 성능을 짜낼 필요가없는
l.groupBy(_._2).mapValues(_.map(_._1)(collection.breakOut): Set[Int])
당신은 아마이 넘어 가지 말았어야합니다. ,이 단계를 구축하는 동안 변경 가능한지도를 사용하여,이되어 무엇을
import collection.generic.CanBuildFrom
import collection.mutable
def toMultiMap[A, K, V, Values](xs: TraversableOnce[A])
(key: A => K)(value: A => V)
(implicit cbfv: CanBuildFrom[Nothing, V, Values]): Map[K, Values] = {
val b = mutable.Map.empty[K, mutable.Builder[V, Values]]
xs.foreach { elem =>
b.getOrElseUpdate(key(elem), cbfv()) += value(elem)
}
b.map { case (k, vb) => (k, vb.result()) } (collection.breakOut)
}
:
그렇지 않으면, 이것은 당신이 값을 수집 유형을 제어 할 수있는 같은 일반적인 toMultiMap
기능을 볼 수있는 방법입니다 변경 가능한 값 Builder
(빌더는 CanBuildFrom
인스턴스에 의해 제공됨)에서 모아진 값이 있습니다. 모든 입력 요소에 대한 반복이 완료된 후, 변경 가능한 빌더 값 맵은 값 콜렉션 유형의 불변 맵으로 변환됩니다 (원하는 출력 콜렉션을 바로 얻으려면 다시 collection.breakOut
트릭 사용).
예는 :
val l = List((1,2,3),(4,2,5),(2,3,3),(10,3,2))
val v = toMultiMap(l)(_._2)(_._1) // uses Vector for values
val s: Map[Int, Set[Int] = toMultiMap(l)(_._2)(_._1) // uses Set for values
그래서 주석이 달린 결과 유형은 값 형식의 형식 유추를 지시합니다. 결과에 주석을 달지 않으면 Scala는 기본 콜렉션 유형으로 Vector
을 선택합니다.
귀하의 솔루션은 괜찮다고 생각합니다. – serejja