Skip to content

Commit 43e040f

Browse files
authored
Merge pull request scala#8113 from szeiger/wip/stringops-collect
Add StringOps#collect methods
2 parents 6961265 + f6cc304 commit 43e040f

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

build.sbt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ val mimaPrereleaseHandlingSettings = Seq(
9090
mimaBinaryIssueFilters ++= Seq(
9191
// Drop after 2.13.0 is out, whence src/reflect/mima-filters/ takes over.
9292
ProblemFilters.exclude[Problem]("scala.reflect.internal.*"),
93+
94+
95+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.collect$extension"),
96+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.collect$extension"),
97+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.collect"),
98+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.collect"),
99+
100+
93101
),
94102
)
95103

src/library/scala/collection/StringOps.scala

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,55 @@ final class StringOps(private val s: String) extends AnyVal {
248248
sb.toString
249249
}
250250

251+
/** Builds a new String by applying a partial function to all chars of this String
252+
* on which the function is defined.
253+
*
254+
* @param pf the partial function which filters and maps the String.
255+
* @return a new String resulting from applying the given partial function
256+
* `pf` to each char on which it is defined and collecting the results.
257+
*/
258+
def collect(pf: PartialFunction[Char, Char]): String = {
259+
var i = 0
260+
var matched = true
261+
def d(x: Char): Char = {
262+
matched = false
263+
0
264+
}
265+
val b = new StringBuilder
266+
while(i < s.length) {
267+
matched = true
268+
val v = pf.applyOrElse(s.charAt(i), d)
269+
if(matched) b += v
270+
i += 1
271+
}
272+
b.result()
273+
}
274+
275+
/** Builds a new collection by applying a partial function to all chars of this String
276+
* on which the function is defined.
277+
*
278+
* @param pf the partial function which filters and maps the String.
279+
* @tparam B the element type of the returned collection.
280+
* @return a new collection resulting from applying the given partial function
281+
* `pf` to each char on which it is defined and collecting the results.
282+
*/
283+
def collect[B](pf: PartialFunction[Char, B]): immutable.IndexedSeq[B] = {
284+
var i = 0
285+
var matched = true
286+
def d(x: Char): B = {
287+
matched = false
288+
null.asInstanceOf[B]
289+
}
290+
val b = immutable.IndexedSeq.newBuilder[B]
291+
while(i < s.length) {
292+
matched = true
293+
val v = pf.applyOrElse(s.charAt(i), d)
294+
if(matched) b += v
295+
i += 1
296+
}
297+
b.result()
298+
}
299+
251300
/** Returns a new collection containing the chars from this string followed by the elements from the
252301
* right hand operand.
253302
*

test/junit/scala/collection/StringOpsTest.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,9 @@ class StringOpsTest {
9797
@Test def withFilterAndThenMap(): Unit = {
9898
assertEquals("hello".withFilter(_ != 'e').map(_.toUpper), "HLLO")
9999
}
100+
101+
@Test def collect: Unit = {
102+
assertEquals("de", "abcdef".collect { case c @ ('b' | 'c') => (c+2).toChar })
103+
assertEquals(Seq('d'.toInt, 'e'.toInt), "abcdef".collect { case c @ ('b' | 'c') => (c+2).toInt })
104+
}
100105
}

0 commit comments

Comments
 (0)