Skip to content

Commit

Permalink
Add StringOps#collect methods
Browse files Browse the repository at this point in the history
Overloaded to produce either a `String` or an `IndexedSeq[B]`, just like `map` and `flatMap`
  • Loading branch information
szeiger committed May 31, 2019
1 parent a73bacc commit 584d69f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/library/scala/collection/StringOps.scala
Expand Up @@ -248,6 +248,55 @@ final class StringOps(private val s: String) extends AnyVal {
sb.toString
}

/** Builds a new String by applying a partial function to all chars of this String
* on which the function is defined.
*
* @param pf the partial function which filters and maps the String.
* @return a new String resulting from applying the given partial function
* `pf` to each char on which it is defined and collecting the results.
*/
def collect(pf: PartialFunction[Char, Char]): String = {
var i = 0
var matched = true
def d(x: Char): Char = {
matched = false
0
}
val b = new StringBuilder
while(i < s.length) {
matched = true
val v = pf.applyOrElse(s.charAt(i), d)
if(matched) b += v
i += 1
}
b.result()
}

/** Builds a new collection by applying a partial function to all chars of this String
* on which the function is defined.
*
* @param pf the partial function which filters and maps the String.
* @tparam B the element type of the returned collection.
* @return a new collection resulting from applying the given partial function
* `pf` to each char on which it is defined and collecting the results.
*/
def collect[B](pf: PartialFunction[Char, B]): immutable.IndexedSeq[B] = {
var i = 0
var matched = true
def d(x: Char): B = {
matched = false
null.asInstanceOf[B]
}
val b = immutable.IndexedSeq.newBuilder[B]
while(i < s.length) {
matched = true
val v = pf.applyOrElse(s.charAt(i), d)
if(matched) b += v
i += 1
}
b.result()
}

/** Returns a new collection containing the chars from this string followed by the elements from the
* right hand operand.
*
Expand Down
5 changes: 5 additions & 0 deletions test/junit/scala/collection/StringOpsTest.scala
Expand Up @@ -97,4 +97,9 @@ class StringOpsTest {
@Test def withFilterAndThenMap(): Unit = {
assertEquals("hello".withFilter(_ != 'e').map(_.toUpper), "HLLO")
}

@Test def collect: Unit = {
assertEquals("de", "abcdef".collect { case c @ ('b' | 'c') => (c+2).toChar })
assertEquals(Seq('d'.toInt, 'e'.toInt), "abcdef".collect { case c @ ('b' | 'c') => (c+2).toInt })
}
}

0 comments on commit 584d69f

Please sign in to comment.