How to flatten an array and convert it into a string? - scala

I have an array in Scala e.g. Array("11","112","as2") and I want to parse it into a string:
"['11','112','as2']"
How can I do it in Scala?

mkString is one way to go. The scala REPL is great for this sort of thing:
scala> Array("11","112","as2")
res0: Array[String] = Array(11, 112, as2)
scala> "['"+res0.mkString("','")+"']"
res1: String = ['11','112','as2']
But if you are creating JSON, perhaps something from your JSON library would be more appropriate?

Related

Read a tuple from a file in Scala

my Task is to read registrations from a file given like:
Keri,345246,2
Ingar,488058,2
Almeta,422016,1
and insert them into a list(Tuple of (String, Int, Int).
So far I wrote this:
The problem is that I don‘t understand why I can't try to cast value2 and value3 to Int even tho they should be Strings because they come from an Array of Strings. Could someone tell me, what my mistake is, I am relatively new to Scala
What is the point of using Scala if you are going to write Java code?
This is how you would properly read a file as a List of case classes.
import scala.io.Source
import scala.util.Using
// Use proper names for the fields.
final case class Registration(field1: String, field2: Int, field3: Int)
// You may change the error handling logic.
def readRegistrationsFromFile(fileName: String): List[Registration] =
Using(Source.fromFile(fileName)) { source =>
source.getLines().map(line => line.split(',').toList).flatMap {
case field1Raw :: field2Raw :: field3Raw :: Nil =>
for {
field2 <- field2Raw.toIntOption
field3 <- field3Raw.toIntOption
} yield Registration(field1 = field1Raw.trim, field2, field3)
case _ =>
None
}.toList
}.getOrElse(default = List.empty)
(feel free to ask any question you may have about this code)
In Scala, in order to convert a String to an Int you need explicit casting.
This can be achieved like this if you are sure the string can be parsed into a integer:
val values = values(1).toInt
If you cannot trust the input (and you probably should not), you can use .toIntOption which will give you a Option[Int] defined if the value was converted successfully or undefined if the string did not represent an integer.
The previous answers are correct. I would add a few more points.
saveContent is declared as a val. This is means it cannot be changed (assigned another value). You can use the Scala REPL (command-line) tool to check:
scala> val saveContent = Nil
val v: collection.immutable.Nil.type = List()
scala> saveContent = 3
^
error: reassignment to val
Instead, you could use a var, although it would be more idiomatic to have an overall pattern like the one provided by Luis Miguel's answer - with pattern-matching and a for-comprehension.
You can use the Scala REPL to check the types of the variables, too. Splitting a String will always lead to more Strings, not Ints, etc.
> val values = "a,2,3".split(",")
val values: Array[String] = Array(a, 2, 3)
> values(2)
val res3: String = 3
This is why a cast like Gael's is necessary.
Array-type access is done with parentheses and not square brackets, in Scala. See above, and http://scalatutorials.com/tour/interactive_tour_of_scala_lists for more details.

Scala Cast List of Any to list of Int

Given a List of Any:
val l = List(2.9940714E7, 2.9931662E7, 2.993162E7, 2.9931625E7, 2.9930708E7, 2.9930708E7, 2.9931477E7)
I need to cast each item to Int.
Works:
l(1).asInstanceOf[Double].toInt
Not:
l.foreach{_.asInstanceOf[Double].toInt}
> java.lang.String cannot be cast to java.lang.Double
If
l.foreach{_.asInstanceOf[String].toDouble.toInt}
> java.lang.Double cannot be cast to java.lang.String
I'm new to Scala. Please tell me what I'm missing.
Why I can cast one item from list, but can't do this via iterator?
Thanks!
It seems as if a String somehow ended up in your List l.
Given a list that is structured like this (with mixed integers, Doubles, and Strings):
val l = List[Any](2.9940714E7, 2.9931625E7, "2.345E8", 345563)
You can convert it to list of integers as follows:
val lAsInts = l.map {
case i: Int => i
case d: Double => d.toInt
case s: String => s.toDouble.toInt
}
println(lAsInts)
This works for Doubles, Ints and Strings. If it still crashes with some exceptions during the cast, then you can add more cases. You can, of course, do the same in a foreach if you want, but in this case it wouldn't do anything, because you don't do anything in the body of foreach except casting. This has no useful side-effects (e.g. it prints nothing).
Another option would be:
lAsInts = l.map{_.toString.toDouble.toInt}
This is in a way even more forgiving to all kind of weird input, at least as long as all values are "numeric" in some sense.
However, this is definitely code-smell: how did you get a list with such a wild mix of values to begin with?
Your given List is of type Double. You can use simply map operation to convert it to Int type. try following code,
val l: List[Double] = List(2.9940714E7, 2.9931662E7, 2.993162E7, 2.9931625E7, 2.9930708E7, 2.9930708E7, 2.9931477E7)
//simply map the list and use toInt
val intLst: List[Int] = l.map(_.toInt)
print(intLst)
//output
//List(29940714, 29931662, 29931620, 29931625, 29930708, 29930708, 29931477)
But suppose you have same List as List[Any] instead then you can use following to convert it to Int.
val l: List[Any] = List(2.9940714E7, 2.9931662E7, 2.993162E7, 2.9931625E7, 2.9930708E7, 2.9930708E7, 2.9931477E7)
val intLst: List[Int] = l.map(_.asInstanceOf[Double].toInt)
It will give same output as above.

Convert String to Set[int] using delimiter in scala

I have a string e.g. "100,123,124" and wanted to convert into Set[Int] data type. e.g Set[100,123,124]
How to convert this in Scala?
Simply use:
"100,123,124".split(",").map(_.toInt).toSet

Scala mkString equivalent in Scoobi Dlist

I am trying to use folds or better yet, mkString to concatenate the strings I have in a DList
val dlist = DList("a", "b", "c")
so that I get a single string : "abc"
Apparently, for a regular list in scala, list.mkString does the job.
Merging a list of Strings using mkString vs foldRight
is there an easy way to do it in scoobi's Distributed Lists?
There's a method DList.fold:
/**Sum up the elements of this distributed list. */
def fold(implicit m: Monoid[A]): DObject[A] =
reduceOption(R.semigroup) map (_ getOrElse m.zero)
Since the type A in your case is String, and scalaz provides an instance Monoid[String], we can use DList.fold:
// make sure there's a Monoid[String] instance in scope
import scalaz._, Scalaz._
val xs = DList("a","b","c")
xs.fold

Accessing Scala data structures in JRuby

It looks like there's some magic translation between Java data structures when accessing them from JRuby; they appear to work like plain ruby maps and arrays. However, Scala data structures don't. I found surprisingly little when googling around for JRuby / Scala interop. How would you, for instance, iterate over Scala's Map and List types?
Sure you can. But it's a bit of hoop-jumping. For lists:
require "/usr/share/scala/lib/scala-library.jar" # load the scala lib
Java::scala.collection.immutable::List.empty.send("::", 1)
.map(lambda{|e|e+1},
Java::scala.collection.immutable.List.canBuildFrom) # by lopex
Now you have a scala list in jruby. You could write some nice Ruby API filling in the implicits for you.
If by "iterate over" you mean use the HOFs (higher-order functions) such as map, reduce, filter , collect and so on then you're going to have trouble. It's possible, but the syntactic elegance you get in Scala comes because it's so easy to write function literals. What the compiler is doing for you when you write something like this:
scala> val l1 = List(1, 2, 3)
l1: List[Int] = List(1, 2, 3)
scala> l1.map(i => i * i)
res0: List[Int] = List(1, 4, 9)
... is create and instantiate a subclass of Function1[Int, Int] whose apply method takes the single Int argument an evaluates the body of the function literal ((i => i * i)).
For you to use any Scala method that accepts a function you'll have to do the same. Something like:
scala> class ISquaredF extends Function1[Int, Int] { def apply(i: Int) = i * i }
defined class ISquaredF
scala> (new ISquaredF)(5)
res1: Int = 25
scala> val isf1 = new ISquaredF
isf1: ISquaredF = <function1>
scala> l1.map(isf1)
res2: List[Int] = List(1, 4, 9)
Overall, it's vastly easier to use Java libraries from Scala than it is to use Scala code from any other JVM language. That's why systems like Akka that want to support both Scala and Java clients have special Java APIs that avoid these parts of the Scala language.