Scala split string to tuple

33,224

Solution 1

You could use pattern matching to extract what you need from the array:

    case class Point(pts: Seq[Double])
    val lines = List("1 1 4.34 2.34")

    val coords = lines.collect(_.split("\\s+") match {
      case Array(s1, s2, points @ _*) => (s1, s2, Point(points.map(_.toDouble)))
    })

Solution 2

How about this:

scala> case class Point(x: Double, y: Double)
defined class Point

scala> s43.split("\\s+") match { case Array(i, j, x, y) => (i.toInt, j.toInt, Point(x.toDouble, y.toDouble)) }
res00: (Int, Int, Point) = (1,1,Point(4.57,0.83))

Solution 3

case class Point(pts: Seq[Double])
val lines = "1 1 4.34 2.34"

val splitLines = lines.split("\\s+") match {
  case Array(s1, s2, points @ _*) => (s1, s2, Point(points.map(_.toDouble)))
}

And for the curious, the @ in pattern matching binds a variable to the pattern, so points @ _* is binding the variable points to the pattern *_ And *_ matches the rest of the array, so points ends up being a Seq[String].

Solution 4

You are not converting the third and fourth tokens into a Point, nor are you converting the lines into a List. Also, you are not rendering each element as a Tuple3, but as a List.

The following should be more in line with what you are looking for.

case class Point(x: Double, y: Double) // Simple point class
Source.fromFile(filename).getLines.map(line => { 
    val tokens = line.split("""\s+""") // Use a regex to avoid empty tokens
    (tokens(0), tokens(1), Point(tokens(2).toDouble, tokens(3).toDouble))
}).toList // Convert from an Iterator to List
Share:
33,224
princess of persia
Author by

princess of persia

Python, MATLAB, Java, C, Data Structure and Algorithms

Updated on July 12, 2020

Comments

  • princess of persia
    princess of persia almost 4 years

    I would like to split a string on whitespace that has 4 elements:

    1 1 4.57 0.83
    

    and I am trying to convert into List[(String,String,Point)] such that first two splits are first two elements in the list and the last two is Point. I am doing the following but it doesn't seem to work:

    Source.fromFile(filename).getLines.map(string => { 
                val split = string.split(" ")
                (split(0), split(1), split(2))
            }).map{t => List(t._1, t._2, t._3)}.toIterator
    
  • princess of persia
    princess of persia over 11 years
    My Point class takes (IndexedSeq[Double]) so how do I get Indexed Seq from tuple?
  • Felix Trepanier
    Felix Trepanier over 11 years
    Simple and clear. You might want to add a case for handling input errors.
  • Ryan K
    Ryan K almost 11 years
    This doesn't compile for me, I added another similar answer that does compile - I couldn't get the code to show up properly in comments. I would be curious to see how collect could be used if someone else knows.
  • pagoda_5b
    pagoda_5b almost 11 years
    from the API of collect "Builds a new collection by applying a partial function to all elements of this list on which the function is defined.". It's just like map but leaves only the elements in the domain of the partial function
  • Capacytron
    Capacytron almost 9 years
    Hm.. I'm getting scala.MatchError: [Ljava.lang.String;@7bfacd5d (of class [Ljava.lang.String;) What do I do wrong?