Are combinations and permutations stable in Scala collections? - scala

Should I rely on the order of combinations and permutations generated by corresponding methods of Scala's collections? For example:
scala> Seq(1, 2, 3).combinations(2).foreach(println)
List(1, 2)
List(1, 3)
List(2, 3)
Can I be sure that I will get my results always in the same precise order?

Well the documentation does not says anything on the order. It just says:
An Iterator which traverses the possible n-element combinations of
this sequence.
So it doesn't guarantee.
Ideally you should always get the order as you printed but it is not guaranteed by the library. So its (pessimistic) safe not to trust it and rather do sort it so that you get the same series always:
scala> import scala.math.Ordering.Implicits._
import scala.math.Ordering.Implicits._
scala> Seq(1,2,3).combinations(2).toList.sorted.foreach(println)
List(1, 2)
List(1, 3)
List(2, 3)

The combinations implementation maintains the order of the elements in the given sequence.
Except that input is processed to group repeated elements together.
The output is not sorted.
scala> Seq(3,2,1).combinations(2).toList
res1: List[Seq[Int]] = List(List(3, 2), List(3, 1), List(2, 1))
The sequence is updated to keep repeated elements together. For instance:
scala> Seq(2,1,3,1,2).combinations(2).toList
res2: List[Seq[Int]] = List(List(2, 2), List(2, 1), List(2, 3), List(1, 1), List(1, 3))
in this case seq is first converted to Seq(2,2,1,1,3):
scala> Seq(2,2,1,1,3).combinations(2).toList
res3: List[Seq[Int]] = List(List(2, 2), List(2, 1), List(2, 3), List(1, 1), List(1, 3))
scala> res2 == res3
res4: Boolean = true

Related

What is the non-flattened Scala Vector of Sets: (1 to 2).flatMap((1 to 3).toSet.subsets(_))?

I can see (1 to 2) is a Range.
scala> (1 to 2)
res20: scala.collection.immutable.Range.Inclusive = Range(1, 2)
I can see the Sets from this Iterator.
scala> (1 to 3).toSet.subsets
res0: Iterator[scala.collection.immutable.Set[Int]] = non-empty iterator
scala> (1 to 3).toSet.subsets.mkString("\n")
res1: String =
Set()
Set(1)
Set(2)
Set(3)
Set(1, 2)
Set(1, 3)
Set(2, 3)
Set(1, 2, 3)
Finally, here is a Vector of Sets when flattened. What is it when not flatted? How can I display it?
scala> (1 to 2).flatMap((1 to 3).toSet.subsets(_))
res19: scala.collection.immutable.IndexedSeq[scala.collection.immutable.Set[Int]] = Vector(Set(1), Set(2), Set(3), Set(1, 2), Set(1, 3), Set(2, 3))
Replacing flatMap with map would give an unflattened list of subsets of different sizes:
(1 to 2).map((1 to 3).toSet.subsets(_).toVector)
// res1: scala.collection.immutable.IndexedSeq[Vector[scala.collection.immutable.Set[Int]]] = Vector(
// Vector(Set(1), Set(2), Set(3)),
// Vector(Set(1, 2), Set(1, 3), Set(2, 3))
// )
Note that since subsets returns an Iterator[Set[A]], toVector converts the Iterators into nested Vectors.

scala - if/else in a for loop

If i use the two for loops like this i get a List[List[Int]], but how can i get a List[Int]?
I dont know how i could write a if/else statement in only one for loop, can someone help me ?
def example: (List[(Int, Int)], Int,Int) => List[Int] ={
(list, p, counter) =>
if (counter >=0)
for(x<-list(i._1); if ( x._1 ==p))yield x._2
for(x<-list(i._1); if ( x._1 !=p))yield example((x._1,x._2+i._2):: Nil,p,counter-1)
else { ....}
}
First off, as written, the code you posted is not even a valid definition. If you have something that works but returns a different type than what is desired, post that working code.
That being said, if you have List[List[Int]] and want a List[Int], the method for that is flatten
Usage:
scala> val nestedList = List(List(1, 2), List(3, 4), List(5, 6))
nestedList: List[List[Int]] = List(List(1, 2), List(3, 4), List(5, 6))
scala> val flattenedList = nestedList.flatten
flattenedList: List[Int] = List(1, 2, 3, 4, 5, 6)

partition an Array with offset

in Clojure I can partition a vector with offset step like
(partition 2 1 [1 2 3 4])
this returns a sequence of lists of n items each at offsets step apart.
for example the previous method returns
((1 2) (2 3) (3 4))
I just wonder how can I acheive the same in Scala
use sliding - Array(1, 2, 3, 4).sliding(2). This would give you an Iterator and you can just call e.g. toArray and get Array[Array[Int]] where internals are as desired.
There is function in the standard library sliding for this purpose
scala> val x = Array(1, 2, 3).sliding(2, 1)
x: Iterator[Array[Int]] = non-empty iterator
scala> x.next
res8: Array[Int] = Array(1, 2)
scala> x.next
res9: Array[Int] = Array(2, 3)
scala> val l = List(1, 2, 3, 4, 5)
l: List[Int] = List(1, 2, 3, 4, 5)
scala> l.sliding(2).toList
res0: List[List[Int]] = List(List(1, 2), List(2, 3), List(3, 4), List(4, 5))
I think this does what you need:
List(1,2,3,4).sliding(2,1).toList

How to sum a list of lists and store them as a lists

Given something like
val list: List[List[Int]] = List(List(5), List(1), List(2), List(3), List(4), List(5, 1), List(5, 2), List(5, 3))
How would one get the list of each sum inner list and return them as a list, i.e.: List(5,1,2,3,4,6,7,8)
I created a function sum which takes a list and returns the sum. I'm unsure how to apply it to each element in this list.. (New to Scala)
You can use a map to do this
list.map(_.sum)
or
list.map(innerList => sum(innerList))
Instead of the custom sum function you could use standard lib sum function
scala> val lists = List(List(1, 2), List(3, 4))
lists: List[List[Int]] = List(List(1, 2), List(3, 4))
scala> lists.map(_.sum)
res11: List[Int] = List(3, 7)

What is Scalas Product.productIterator supposed to do?

Can someone tell me why I am getting different results when using Tuple2[List,List] and List[List] as my Product in the code below? Specifically I would like to know why the second value of the list of lists gets wrapped in another list?
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)
scala> val c = List(a,b)
c: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6))
scala> c.productIterator.foreach( println(_) )
List(1, 2, 3)
List(List(4, 5, 6)) // <-- Note this
scala> val d = (a,b)
d: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5, 6))
scala> d.productIterator.foreach( println(_) )
List(1, 2, 3)
List(4, 5, 6) // <-- Compared to this
(I have read the (absolutely minimal) description of Scala's Product and the productIterator method on http://www.scala-lang.org/api/current/index.html#scala.Product )
Basically, Tuple means a product between all of its elements, but a non-empty List is a product between its head and tail.
This happens for List, because all case classes extend Product, and represent a product between all their elements similar to tuples. And non-empty List is defined as a case class, containing head and tail: final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B], which inherits the default implementation of Product by case class.
You can observe more of this behaviour with other Lists with 1 or more than 2 elements:
scala> List(a).productIterator.foreach(println)
List(1, 2, 3)
List()
scala> List(a, a).productIterator.foreach(println)
List(1, 2, 3)
List(List(1, 2, 3))
scala> List(a, a, a).productIterator.foreach(println)
List(1, 2, 3)
List(List(1, 2, 3), List(1, 2, 3))