[SCALA] 규모 :지도 병합
SCALA규모 :지도 병합
어떻게하면 아래와 같은지도를 병합 할 수 있습니다 :
Map1 = Map(1 -> Class1(1), 2 -> Class1(2))
Map2 = Map(2 -> Class2(1), 3 -> Class2(2))
후 합병했다.
Merged = Map( 1 -> List(Class1(1)), 2 -> List(Class1(2), Class2(1)), 3 -> Class2(2))
목록, 설정 또는 크기 속성이 다른 수집 할 수 있습니다.
해결법
-
==============================
1.다음과 같이 표준 라이브러리를 사용하여, 당신은 그것을 할 수 있습니다 :
다음과 같이 표준 라이브러리를 사용하여, 당신은 그것을 할 수 있습니다 :
// convert maps to seq, to keep duplicate keys and concat val merged = Map(1 -> 2).toSeq ++ Map(1 -> 4).toSeq // merged: Seq[(Int, Int)] = ArrayBuffer((1,2), (1,4)) // group by key val grouped = merged.groupBy(_._1) // grouped: scala.collection.immutable.Map[Int,Seq[(Int, Int)]] = Map(1 -> ArrayBuffer((1,2), (1,4))) // remove key from value set and convert to list val cleaned = grouped.mapValues(_.map(_._2).toList) // cleaned: scala.collection.immutable.Map[Int,List[Int]] = Map(1 -> List(2, 4))
-
==============================
2.이것은 내가 가지고 올 수있는 간단한 구현
이것은 내가 가지고 올 수있는 간단한 구현
val m1 = Map(1 -> "1", 2 -> "2") val m2 = Map(2 -> "21", 3 -> "3") def merge[K, V](m1:Map[K, V], m2:Map[K, V]):Map[K, List[V]] = (m1.keySet ++ m2.keySet) map { i => i -> (m1.get(i).toList ::: m2.get(i).toList) } toMap merge(m1, m2) // Map(1 -> List(1), 2 -> List(2, 21), 3 -> List(3))
-
==============================
3.당신은 scalaz를 사용할 수 있습니다 :
당신은 scalaz를 사용할 수 있습니다 :
import scalaz._, Scalaz._ val m1 = Map('a -> 1, 'b -> 2) val m2 = Map('b -> 3, 'c -> 4) m1.mapValues{List(_)} |+| m2.mapValues{List(_)} // Map('b -> List(2, 3), 'c -> List(4), 'a -> List(1))
당신은지도에있는 값으로 설정을 얻기 위해 설정 (_) 대신 목록 (_)을 사용할 수 있습니다.
scalaz의 컨닝 페이퍼에 반군을 참조하십시오 (또는 scalaz을 학습)에 대한 자세한 내용은 | + | 운영자.
인터넷 용 | + | + | | - 목록 +로 작동 ++로지도를 위해 적용 동일한 키 값.
-
==============================
4.나는 이것에 대해 블로그 포스트를 작성, 그것을 체크 아웃 :
나는 이것에 대해 블로그 포스트를 작성, 그것을 체크 아웃 :
http://www.nimrodstech.com/scala-map-merge/
기본적으로 scalaz 반 그룹을 사용하면 아주 쉽게이를 수 있습니다
같이 보일 것입니다 :
import scalaz.Scalaz._ Map1 |+| Map2
-
==============================
5.한 깨끗한 방법은 고양이와 함께, 그것을 할 수 있습니다 :
한 깨끗한 방법은 고양이와 함께, 그것을 할 수 있습니다 :
import cats.implicits._ Map(1 -> "Hello").combine(Map(2 -> "Goodbye")) //Map(2 -> Goodbye, 1 -> Hello)
이 두지도는 동일한 유형 (이 경우, 맵 [INT, 문자열])이 될 필요가 있음을주의하는 것이 중요합니다.
긴 설명 :
결합 정말지도의 구성원이 아닙니다. cats.implicits를 가져 오면 당신은 간결한 구문을 수 있도록 몇 가지 암시 클래스와 함께, 내장 된 모노 이드 인스턴스 범위 고양이의지도로 데려 와야합니다.
상기이 동등하다 :
Monoid[Map[Int, String]].combine(Map(1 -> "Hello"), Map(2 -> "Goodbye"))
우리가 범위의 모노 이드 [맵 [INT, 문자열]] 인스턴스를 얻기 위해 모노 이드 "소환"기능을 사용하여 사용하는 경우 그 기능을 결합합니다.
-
==============================
6.동일한 유형의 두지도를 병합 foldLeft을 사용할 수 있습니다
동일한 유형의 두지도를 병합 foldLeft을 사용할 수 있습니다
def merge[A, B](a: Map[A, B], b: Map[A, B])(mergef: (B, Option[B]) => B): Map[A, B] = { val (big, small) = if (a.size > b.size) (a, b) else (b, a) small.foldLeft(big) { case (z, (k, v)) => z + (k -> mergef(v, z.get(k))) } } def mergeIntSum[A](a: Map[A, Int], b: Map[A, Int]): Map[A, Int] = merge(a, b)((v1, v2) => v2.map(_ + v1).getOrElse(v1))
예:
val a = Map("a" -> 1, "b" -> 5, "c" -> 6) val b = Map("a" -> 4, "z" -> 8) mergeIntSum(a, b) res0: Map[String,Int] = Map(a -> 5, b -> 5, c -> 6, z -> 8)
-
==============================
7.스칼라 2.13부터 만 표준 라이브러리에 기초하여 또 다른 해결책은 (그 이름에서 알 수 있듯이) mapValues 뒤에 GROUPBY의 상당에서는 groupMap를 사용하여 구성되어
스칼라 2.13부터 만 표준 라이브러리에 기초하여 또 다른 해결책은 (그 이름에서 알 수 있듯이) mapValues 뒤에 GROUPBY의 상당에서는 groupMap를 사용하여 구성되어
// val m1 = Map(1 -> "a", 2 -> "b") // val m2 = Map(2 -> "c", 3 -> "d") (m1.toSeq ++ m2).groupMap(_._1)(_._2) // Map[Int,Seq[String]] = Map(2 -> List("b", "c"), 1 -> List("a"), 3 -> List("d"))
이:
-
==============================
8.당신이 원래의지도를 허비하지 않으려면 다음과 같은 일을 할 수있는
당신이 원래의지도를 허비하지 않으려면 다음과 같은 일을 할 수있는
val target = map1.clone() val source = map2.clone() source.foreach(e => target += e._1 -> e._2)
-
==============================
9.
left.keys map { k => k -> List(left(k),right(k)) } toMap
간결하고 두 개의지도가 좌우되는 가정 작동합니다. 효율이 확실하지 않음.
그러나 귀하의 질문은 두 가지 이유로, 조금 모호합니다. 당신은 지정하지 않는
첫 번째 경우를 들어, 다음 예제를 고려하십시오
val left = Map("foo" ->1, "bar" ->2) val right = Map("bar" -> 'a', "foo" -> 'b')
어떤 결과
res0: Map[String,List[Int]] = Map(foo -> List(1, 98), bar -> List(2, 97))
숯을 때문에 스칼라 유형 계층 구조의,의 int로 변환 된 방법을 알 수 있습니다. 귀하의 예를 들어 클래스 1과 Class2의에 관련이없는 경우보다 일반적으로, 당신은 목록 [모든]을 다시 얻을 것; 이것은 아마 당신이 원하지 없습니다.
당신은 내 대답에서 목록 생성자를 놓는 방법으로이 문제를 해결할 수있다; 이 유형을 유지하는 튜플을 반환합니다 :
res0: Map[String,(Int, Char)] = Map(foo -> (1,b), bar -> (2,a))
두 번째 문제는 같은 키가없는지도가있을 때 발생하는 것입니다. 이는 키가 아닌 발견 예외가 발생합니다. 또 다른 방법으로 넣어, 당신은 오른쪽 왼쪽을하고, 또는 내부는 두지도의 조인입니까? 당신은 권리를 위해 right.keys 또는 right.keySet ++ left.keySet로 전환하여 조인의 종류를 명확하게 할 수 / 내부는 각각 합류했다. 후자는 누락 된 핵심 문제를 해결하지만, 어쩌면 당신이 왼쪽을 원하거나를 대신 가입 즉 아마 원하는 게 아니에요. 이 경우 당신은, 예를 들어, 값을 모든 키 수익률을 보장하기 위해지도의 withDefault 방법을 고려할 수 있습니다 없음, 그러나 이것은 조금 더 많은 작업을 필요로하지 않는다.
-
==============================
10.
m2.foldLeft(m1.mapValues{List[CommonType](_)}) { case (acc, (k, v)) => acc.updated(k, acc.getOrElse(k, List.empty) :+ v) }
jwvh에서 언급 한 바와 같이, 목록 유형은 클래스 1은 Class2의 행 위 형식이 아닌 경우 명시 적으로 지정해야합니다. CommonType는 클래스 1과 Class2의 모두 상한 인 유형입니다.
-
==============================
11.솔루션이 개지도를 결합하기 : 맵 [A, B], 결과 유형 :지도 [A, 목록 [B] (@ 데이비드 카 스틸로가 제공하는 약간 개선 된 버전) 스칼라 고양이를 통해
솔루션이 개지도를 결합하기 : 맵 [A, B], 결과 유형 :지도 [A, 목록 [B] (@ 데이비드 카 스틸로가 제공하는 약간 개선 된 버전) 스칼라 고양이를 통해
// 각 원래지도 [A, 목록 [B]]지도로 변환합니다. // 목록을 결합하는 범위에 모노 이드 [목록]의 인스턴스를 추가 :
import cats.instances.map._ // for Monoid import cats.syntax.semigroup._ // for |+| import cats.instances.list._ val map1 = Map("a" -> 1, "b" -> 2) .mapValues(List(_)) val map2 = Map("b" -> 3, "d" -> 4) .mapValues(List(_)) map1 |+| map2
-
==============================
12.mergeByKey 같은 매우 유용한 방법을 제공 스칼라 수집-있는 contrib라는 스칼라 모듈은있다.
mergeByKey 같은 매우 유용한 방법을 제공 스칼라 수집-있는 contrib라는 스칼라 모듈은있다.
첫째, 우리는 build.sbt에 추가 종속성을 추가해야합니다
libraryDependencies += "org.scala-lang.modules" %% "scala-collection-contrib" % "0.1.0"
후는 다음과 같이 병합 할 수있다 :
import scala.collection.decorators._ val map1 = Map(1 -> Class1(1), 2 -> Class1(2)) val map2 = Map(2 -> Class2(1), 3 -> Class2(2)) map1.mergeByKeyWith(map2){ case (a,b) => a.toList ++ b.toList }
from https://stackoverflow.com/questions/20047080/scala-merge-map by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라 2.10에 반사를 통해 유형 매개 변수를 찾기? (0) | 2019.11.02 |
---|---|
[SCALA] 때문에 긴 RDD 리니지에 유래 (0) | 2019.11.02 |
[SCALA] 어떻게 벡터의 열을 합계를 사용자 정의 집계 함수를 정의? (0) | 2019.11.02 |
[SCALA] 새로운 스칼라 반사 API와 동반자 객체의 인스턴스를 가져옵니다 (0) | 2019.11.02 |
[SCALA] 스칼라 메소드 호출에서 괄호에 대한 규칙은 무엇인가? (0) | 2019.11.02 |