Skip to content

Commit 962ea7a

Browse files
committed
Merge remote-tracking branch 'origin/main' into update/latest
2 parents 8e84fd3 + a6b139b commit 962ea7a

File tree

5 files changed

+94
-6
lines changed

5 files changed

+94
-6
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ lazy val collectionContrib = crossProject(JVMPlatform, JSPlatform, NativePlatfor
4545
case _ => Seq.empty
4646
}
4747
},
48-
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s", "-a"),
48+
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-s", "-a"),
4949
Test / parallelExecution := false, // why?
5050
libraryDependencies ++= Seq(
5151
"junit" % "junit" % "4.13.2" % Test,

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.10.0
1+
sbt.version=1.10.1

project/plugins.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "3.1.0")
22
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2")
33
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2")
44
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
5-
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17")
5+
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.4")

src/main/scala/scala/collection/decorators/MapDecorator.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,16 @@ class MapDecorator[C, M <: IsMap[C]](coll: C)(implicit val map: M) {
5959
*/
6060
def mergeByKeyWith[W, X, That](other: Map[map.K, W])(f: PartialFunction[(Option[map.V], Option[W]), X])(implicit bf: BuildFrom[C, (map.K, X), That]): That = {
6161
val b = bf.newBuilder(coll)
62-
val traversed = mutable.Set.empty[W]
62+
val traversed = mutable.Set.empty[map.K]
6363
val pf = f.lift
6464
for {
6565
(k, v) <- map(coll)
66-
x <- pf(other.get(k).fold[(Option[map.V], Option[W])]((Some(v), None)){ w => traversed += w; (Some(v), Some(w)) })
66+
x <- pf(other.get(k).fold[(Option[map.V], Option[W])]((Some(v), None)){ w => traversed += k; (Some(v), Some(w)) })
6767
} {
6868
b += k -> x
6969
}
7070
for {
71-
(k, w) <- other if !traversed(w)
71+
(k, w) <- other if !traversed(k)
7272
x <- pf((None, Some(w)))
7373
} {
7474
b += k -> x

src/test/scala/scala/collection/decorators/MapDecoratorTest.scala

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,92 @@ class MapDecoratorTest {
7474
// Assert.assertEquals(expected, zipped2)
7575
}
7676

77+
@Test
78+
def mergingByKeyPerformsFullOuterJoin(): Unit = {
79+
val arthur = "arthur.txt"
80+
81+
val tyson = "tyson.txt"
82+
83+
val sandra = "sandra.txt"
84+
85+
val allKeys = Set(arthur, tyson, sandra)
86+
87+
val sharedValue = 1
88+
89+
val ourChanges = Map(
90+
(
91+
arthur,
92+
sharedValue
93+
),
94+
(
95+
tyson,
96+
2
97+
)
98+
)
99+
100+
locally {
101+
// In this test case, none of the associated values collide across keys...
102+
103+
val theirChanges = Map(
104+
(
105+
arthur,
106+
sharedValue
107+
),
108+
(
109+
sandra,
110+
3
111+
)
112+
)
113+
114+
Assert.assertEquals("Expect the same keys to appear in the join taken either way around.", ourChanges.mergeByKey(theirChanges).keySet, theirChanges
115+
.mergeByKey(ourChanges)
116+
.keySet)
117+
118+
Assert.assertTrue("Expect the same associated values to appear in the join taken either way around, albeit swapped around and not necessarily in the same key order.",
119+
ourChanges
120+
.mergeByKey(theirChanges)
121+
.values
122+
.map(_.swap)
123+
.toList
124+
.sorted
125+
.sameElements(theirChanges.mergeByKey(ourChanges).values.toList.sorted))
126+
127+
Assert.assertEquals("Expect all the keys to appear in an outer join.", ourChanges.mergeByKey(theirChanges).keySet, allKeys)
128+
129+
Assert.assertEquals("Expect all the keys to appear in an outer join.", theirChanges.mergeByKey(ourChanges).keySet, allKeys)
130+
}
131+
132+
locally {
133+
// In this test case, associated values collide across keys...
134+
135+
val theirChangesRedux = Map(
136+
(
137+
arthur,
138+
sharedValue
139+
),
140+
(
141+
sandra,
142+
sharedValue
143+
)
144+
)
145+
146+
Assert.assertEquals("Expect the same keys to appear in the join taken either way around.", ourChanges.mergeByKey(theirChangesRedux).keySet, theirChangesRedux
147+
.mergeByKey(ourChanges)
148+
.keySet)
149+
150+
Assert.assertTrue("Expect the same associated values to appear in the join taken either way around, albeit swapped around and not necessarily in the same key order.",
151+
ourChanges
152+
.mergeByKey(theirChangesRedux)
153+
.values
154+
.map(_.swap)
155+
.toList
156+
.sorted
157+
.sameElements(theirChangesRedux.mergeByKey(ourChanges).values.toList.sorted))
158+
159+
Assert.assertEquals("Expect all the keys to appear in an outer join.", ourChanges.mergeByKey(theirChangesRedux).keySet, allKeys)
160+
161+
Assert.assertEquals("Expect all the keys to appear in an outer join.", theirChangesRedux.mergeByKey(ourChanges).keySet, allKeys)
162+
}
163+
}
164+
77165
}

0 commit comments

Comments
 (0)