Skip to content

Commit ee66287

Browse files
committed
Adding splitAsList to String
1 parent 8359245 commit ee66287

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package scala
2+
package next
3+
4+
private[next] final class NextStringOpsExtensions(
5+
private val str: String
6+
) extends AnyVal {
7+
/** Split this string around the separator character; as a [[List]]
8+
*
9+
* If this string is blank,
10+
* returns an empty list.
11+
*
12+
* If this string is not a blank string,
13+
* returns a list containing the substrings terminated by the start of the string,
14+
* the end of the string or the separator character.
15+
*
16+
* By default, this method discards empty substrings.
17+
*
18+
* @param separator the character used as the delimiter.
19+
* @param preserveEmptySubStrings set as `true` to preserve empty substrings.
20+
* @return a [[List]] of substrings.
21+
*/
22+
def splitAsList(separator: Char, preserveEmptySubStrings: Boolean = false): List[String] = {
23+
@annotation.tailrec
24+
def loop(currentIdx: Int, acc: List[String]): List[String] = {
25+
def addToAcc(substring: String): List[String] =
26+
if (substring.isEmpty && !preserveEmptySubStrings)
27+
acc
28+
else
29+
substring :: acc
30+
31+
val newIndex = str.lastIndexOf(separator, currentIdx - 1)
32+
if (newIndex == -1)
33+
addToAcc(substring = str.substring(0, currentIdx))
34+
else
35+
loop(
36+
currentIdx = newIndex,
37+
acc = addToAcc(substring = str.substring(newIndex + 1, currentIdx))
38+
)
39+
}
40+
41+
if (str.forall(_.isWhitespace))
42+
List.empty
43+
else
44+
loop(
45+
currentIdx = str.length,
46+
acc = List.empty
47+
)
48+
}
49+
}

src/main/scala/scala/next/package.scala

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
package scala
1414

15+
import scala.language.implicitConversions
16+
1517
package object next {
1618
implicit final class OptionOpsExtensions[A](private val v: Option[A]) extends AnyVal {
1719
/** Apply the side-effecting function `f` to the option's value
@@ -22,4 +24,9 @@ package object next {
2224
*/
2325
def tapEach[B](f: A => B): Option[A] = { v.foreach(f); v }
2426
}
27+
28+
implicit final def scalaNextSyntaxForStringOps(
29+
str: String
30+
): NextStringOpsExtensions =
31+
new NextStringOpsExtensions(str)
2532
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.next
14+
15+
import org.junit.Assert._
16+
import org.junit.Test
17+
18+
final class TestStringOpsExtensions {
19+
@Test
20+
def splitAsListEmpty(): Unit = {
21+
val str = ""
22+
23+
assertTrue(str.splitAsList(',').isEmpty)
24+
}
25+
26+
@Test
27+
def splitAsListBlankString(): Unit = {
28+
val strings = List(
29+
" ",
30+
" ",
31+
"\t",
32+
"\t\t\t",
33+
"\n",
34+
"\n\n\n",
35+
" \t \t \n"
36+
)
37+
38+
strings.foreach { str =>
39+
assertTrue(str.splitAsList(',').isEmpty)
40+
}
41+
}
42+
43+
@Test
44+
def splitAsListDelimiterNotFound(): Unit = {
45+
val str = "Hello World"
46+
val expected = List(str)
47+
48+
assertEquals(expected, str.splitAsList(','))
49+
}
50+
51+
@Test
52+
def splitAsListSingleDelimiter(): Unit = {
53+
val str = "Hello,World"
54+
val expected = List("Hello", "World")
55+
56+
assertEquals(expected, str.splitAsList(','))
57+
}
58+
59+
@Test
60+
def splitAsListMultipleDelimiters(): Unit = {
61+
val str = "Hello,World,Good,Bye,World"
62+
val expected = List("Hello", "World", "Good", "Bye", "World")
63+
64+
assertEquals(expected, str.splitAsList(','))
65+
}
66+
67+
@Test
68+
def splitAsListEmptySubStrings(): Unit = {
69+
val str = "Hello,,World,"
70+
val expected = List("Hello", "World")
71+
72+
assertEquals(expected, str.splitAsList(','))
73+
}
74+
75+
@Test
76+
def splitAsListDelimiterAtTheEnd(): Unit = {
77+
val str = "Hello,World,"
78+
val expected = List("Hello", "World")
79+
80+
assertEquals(expected, str.splitAsList(','))
81+
}
82+
83+
@Test
84+
def splitAsListDelimiterAtTheBeginning(): Unit = {
85+
val str = ",Hello,World"
86+
val expected = List("Hello", "World")
87+
88+
assertEquals(expected, str.splitAsList(','))
89+
}
90+
91+
@Test
92+
def splitAsListPreserveEmptySubStrings(): Unit = {
93+
val str = ",Hello,,World,"
94+
val expected = List("", "Hello", "", "World", "")
95+
96+
assertEquals(expected, str.splitAsList(separator = ',', preserveEmptySubStrings = true))
97+
}
98+
}

0 commit comments

Comments
 (0)