It appears the toSeq method in Scala collections returns a scala.collection.Seq, I could also return a Traversable or Iterable but need to convert this to a scala.collection.immutable.Seq.
Is there an easy way to do this?
Thanks
Richard
Use the to method to convert between arbitrary collection types in Scala 2.10:
scala> Array(1, 2, 3).toSeq
res0: Seq[Int] = WrappedArray(1, 2, 3)
scala> Array(1, 2, 3).to[collection.immutable.Seq]
res1: scala.collection.immutable.Seq[Int] = Vector(1, 2, 3)
Related
scala> Array(1, 2, 3).toString
res1: String = [I#11cf437c
scala> List(1, 2, 3).toString
res2: String = List(1, 2, 3)
scala> Vector(1, 2, 3).toString
res3: String = Vector(1, 2, 3)
Logically, one would expect Array(1, 2, 3).toString to return "Array(1, 2, 3)".
Update: seems to me like Array maps to the built in Java array type—is this correct? and if yes, is this the reason Array.toString has to behave like this?
It is because Array is a Java object. You can however use runtime.ScalaRunTime.stringOf if it suits your needs.
scala> runtime.ScalaRunTime.stringOf(Array(1, 2, 3))
res3: String = Array(1, 2, 3)
scala> List(1,2,3).getClass()
res0: Class[_ <: List[Int]] = class scala.collection.immutable.$colon$colon
scala> Vector(1,2,3).getClass()
res1: Class[_ <: scala.collection.immutable.Vector[Int]] = class scala.collection.immutable.Vector
scala> Array(1,2,3).getClass()
res2: Class[_ <: Array[Int]] = class [I
List and Vector are Scala classes, so they have a nice representation. Array comes from Java and practices Java's ugliness.
What's the best way to convert a List of Lists in scala (2.9)?
I have a list:
List[List[A]]
which I want to convert into
List[A]
How can that be achieved recursively? Or is there any other better way?
List has the flatten method. Why not use it?
List(List(1,2), List(3,4)).flatten
> List(1,2,3,4)
.flatten is obviously the easiest way, but for completeness you should also know about flatMap
val l = List(List(1, 2), List(3, 4))
println(l.flatMap(identity))
and the for-comprehension equivalent
println(for (list <- l; x <- list) yield x)
flatten is obviously a special case of flatMap, which can do so much more.
Given the above example, I'm not sure you need recursion. Looks like you want List.flatten instead.
e.g.
scala> List(1,2,3)
res0: List[Int] = List(1, 2, 3)
scala> List(4,5,6)
res1: List[Int] = List(4, 5, 6)
scala> List(res0,res1)
res2: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6))
scala> res2.flatten
res3: List[Int] = List(1, 2, 3, 4, 5, 6)
If your structure can be further nested, like:
List(List(1, 2, 3, 4, List(5, 6, List(7, 8))))
This function should give you the desire result:
def f[U](l: List[U]): List[U] = l match {
case Nil => Nil
case (x: List[U]) :: tail => f(x) ::: f(tail)
case x :: tail => x :: f(tail)
}
You don't need recursion but you can use it if you want:
def flatten[A](list: List[List[A]]):List[A] =
if (list.length==0) List[A]()
else list.head ++ flatten(list.tail)
This works like flatten method build into List. Example:
scala> flatten(List(List(1,2), List(3,4)))
res0: List[Int] = List(1, 2, 3, 4)
If you want to use flatmap, here is the the way
Suppose that you have a List of List[Int] named ll, and you want to flat it to List,
many people already gives you the answers, such as flatten, that's the easy way. I assume that you are asking for using flatmap method. If it is the case, here is the way
ll.flatMap(_.map(o=>o))
Is there any concise way to convert a Seq into ArrayBuffer in Scala?
scala> val seq = 1::2::3::Nil
seq: List[Int] = List(1, 2, 3)
scala> seq.toBuffer
res2: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2, 3)
EDIT After Scala 2.1x, there is a method .to[Coll] defined in TraversableLike, which can be used as follow:
scala> import collection.mutable
import collection.mutable
scala> seq.to[mutable.ArrayBuffer]
res1: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
scala> seq.to[mutable.Set]
res2: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
This will work:
ArrayBuffer(mySeq : _*)
Some explanations: this uses the apply method in the ArrayBuffer companion object. The signature of that method is
def apply [A] (elems: A*): ArrayBuffer[A]
meaning that it takes a variable number of arguments. For instance:
ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8)
is also a valid call. The ascription : _* indicates to the compiler that a Seq should be used in place of that variable number of arguments (see Section 4.6.2 in the Scala Reference).
How does one convert a Scala Array to a mutable.Set?
It's easy to convert to an immutable.Set:
Array(1, 2, 3).toSet
But I can't find an obvious way to convert to a mutable.Set.
scala> val s=scala.collection.mutable.Set()++Array(1,2,3)
s: scala.collection.mutable.Set[Int] = Set(2, 1, 3)
scala> scala.collection.mutable.Set( Array(1,2) :_* )
res2: scala.collection.mutable.Set[Int] = Set(2, 1)
The weird :_* type ascription, forces factory method to see the array as a list of arguments.
Starting Scala 2.10, via factory builders applied with .to(factory):
Array(1, 2, 3).to[collection.mutable.Set]
// collection.mutable.Set[Int] = Set(1, 2, 3)
And starting Scala 2.13:
Array(1, 2, 3).to(collection.mutable.Set)
// collection.mutable.Set[Int] = HashSet(1, 2, 3)
I have a Tuple2 of List[List[String]] and I'd like to be able to convert the tuple to a list so that I can then use List.transpose(). Is there any way to do this? Also, I know it's a Pair, though I'm always a fan of generic solutions.
Works with any tuple (scala 2.8):
myTuple.productIterator.toList
Scala 2.7:
(0 to (myTuple.productArity-1)).map(myTuple.productElement(_)).toList
Not sure how to maintain type info for a general Product or Tuple, but for Tuple2:
def tuple2ToList[T](t: (T,T)): List[T] = List(t._1, t._2)
You could, of course, define similar type-safe conversions for all the Tuples (up to 22).
Using Shapeless -
# import syntax.std.tuple._
import syntax.std.tuple._
# (1,2,3).toList
res21: List[Int] = List(1, 2, 3)
# (1,2,3,4,3,3,3,3,3,3,3).toList
res22: List[Int] = List(1, 2, 3, 4, 3, 3, 3, 3, 3, 3, 3)
Note that type information is not lost using Shapeless's toList.