Get first 2 values ​​in comma separated string

I am trying to get the first 2 values ​​of a comma separated string in scala. for example

a,b,this is a test

      

How to store the values ​​a, b in two separate variables?

+3


source to share


5 answers


To make it easy and clean.

KISS solution:

1.Use split to split. Then use take , which is defined for all ordered sequences, to get the elements you want:



scala> val res = "a,b,this is a test" split ',' take 2
res: Array[String] = Array(a, b)

      

2.Use pattern matching to set variables:

scala> val Array(x,y) = res
x: String = a
y: String = b*

      

+6


source


Are you looking for a method split

?

"a,b,this is a test".split(',')
res0: Array[String] = Array(a, b, this is a test)

      



If you only want the first two values, you need to do something like:

val splitted = "a,b,this is a test".split(',')
val (first, second) = (splitted(0), splitted(1))

      

+3


source


Another solution using Sequence Pattern match

in Scala enter link here

Welcome to Scala version 2.11.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_65).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val str = "a,b,this is a test"
str: String = a,b,this is a test

scala> val Array(x, y, _*) = str.split(",")
x: String = a
y: String = b


scala> println(s"x = $x, y = $y")
x = a, y = b

      

+3


source


There should be some regex options here.

scala> val s = "a,b,this is a test"
s: String = a,b,this is a test

scala> val r = "[^,]+".r
r: scala.util.matching.Regex = [^,]+

scala> r findAllIn s
res0: scala.util.matching.Regex.MatchIterator = non-empty iterator

scala> .toList
res1: List[String] = List(a, b, this is a test)

scala> .take(2)
res2: List[String] = List(a, b)

scala> val a :: b :: _ = res2
a: String = a
b: String = b

      

but

scala> val a :: b :: _ = (r findAllIn "a" take 2).toList
scala.MatchError: List(a) (of class scala.collection.immutable.$colon$colon)
  ... 33 elided

      

or if you are not sure if there is a second item, for example:

scala> val r2 = "([^,]+)(?:,([^,]*))?".r.unanchored
r2: scala.util.matching.UnanchoredRegex = ([^,]+)(?:,([^,]*))?

scala> val (a,b) = "a" match { case r2(x,y) => (x, Option(y)) }
a: String = a
b: Option[String] = None

scala> val (a,b) = s match { case r2(x,y) => (x, Option(y)) }
a: String = a
b: Option[String] = Some(b)

      

It is slightly better if the records are long lines.

Footnote: Example variations look better with a regex interpolator.

+1


source


If your string is short you can just use String.split

and take the first two elements.

val myString = "a,b,this is a test"
val splitString = myString.split(',') // Scala adds a split-by-character method in addition to Java split-by-regex
val a = splitString(0)
val b = splitString(1)

      

Another solution would be to use a regular expression to extract the first two elements. I think this is pretty elegant.

val myString = "a,b,this is a test"
val regex = """(.*),(.*),.*""".r    // all groups (in parenthesis) will be extracted.
val regex(a, b) = myString          // a="a", b="b"

      

You can of course tweak the regex to allow non-empty tokens (or whatever else you need to check):

val regex = """(.+),(.+),.+""".r

      

Note that in my examples I assumed that the string always had at least two tokens. In the first example, you can check the length of the array if needed. The second will throw a MatchError if the regex doesn't match the string.


I originally suggested the following solution. I'll leave it because it works and doesn't use a class officially marked as deprecated, but the Javadoc for StringTokenizer mentions that it is a deprecated class and should no longer be used.

val myString = "a,b,this is a test"
val st = new StringTokenizer(",");
val a = st.nextToken()
val b = st.nextToken()
// You could keep calling st.nextToken(), as long as st.hasMoreTokens is true

      

0


source







All Articles