Scala: Generate tuple of Ints - scala

I want to generate a Vector of tuple of two Ints. For now, I do as follows:
(0 until 100).map(x => (x+1 until 100).map(y => (x,y))).flatten.filter { ... }
I wondered if there were any more efficient way to do this. I have the feeling that "flatten" slows down the code. Do I have to use "flatten" or can I use something else ?
PS1: If I don't use "flatten", I have: Vector(Vector(a,b),Vector(c,d),...) and not Vector((a,b),(c,d),...).
PS2: I use (x+1 until 100) in the second generator as I'm not interested in having tuples (a,b) and (b,a).

for {
i <- 0 until 100
j <- i+1 until 100
} yield (i,j)

map(f).flatten can be shortened to flatMap(f), so you'll get
(0 until 100).flatMap(x => (x+1 until 100).map(y => (x,y))).filter(...)
This is equivalent to Tzach Zohar's answer, but you can see the relation. It may also be worthwhile to move filter inside flatMap (it will get called more times, but you'll get smaller intermediate collections).

Related

scala call tuple element with variable

I'm new to scala and I'm trying to figure out how tuple works. I'm trying to call the xth element of a tuplle where x is a variable but it seems not to work, how should I do?
for (x <- 1 to 2; j <- 0 to (N-1)) yield((j, index._x), (x-1,index._x))
In particular the index._x seem to not work
It is possible to do this using the Product trait, though, as mentioned in the comment, this is not really a good idea or the intended way tuples are supposed to be used:
val indexed = index.productIterator.toIndexedSeq
for {
x <- 1 to 2
j <- 0 until N
} yield ((j, indexed(x-1)), (x-1, indexed(x-1))
or better yet (get rid of indexed access, it's yuky):
index.productIterator.take(2).toSeq.zipWithIndex
.flatMap { case (value, index) =>
(0 until N).map { j => ((j, value), (index, value)) }
}
I'll say it again though: there is about 99% chance there is a better way to do what you are actually trying to do. Tuples are meant for grouping data, not iterating over it (use collections for that).

Upper Triangular Matrix in Scala

Is there a way I can perform a faster computation of upper triangle matrix in scala?
/** Returns a vector which consists of the upper triangular elements of a matrix */
def getUpperTriangle(A: Array[Array[Double]]) =
{
var A_ = Seq(0.)
for (i <- 0 to A.size - 1;j <- 0 to A(0).size - 1)
{
if (i <= j){
A_ = A_ ++ Seq(A(i)(j))
}
}
A_.tail.toArray
}
I don't know about faster, but this is a lot shorter and more "functional" (I note you tagged your question with functional-programming)
def getUpperTriangle(a: Array[Array[Double]]) =
(0 until a.size).flatMap(i => a(i).drop(i)).toArray
or, more or less same idea:
def getUpperTriangle(a: Array[Array[Double]]) =
a.zipWithIndex.flatMap{case(r,i) => r.drop(i)}
Here are three basic things you can do to streamline your logic to improve performance:
Start with an empty Seq, so you don't have to call Seq.tail at the end. The tail operation is going to be O(n), since the Seq factory methods give you an IndexedSeq
Use Seq.:+ to append a single element to the Seq, instead of constructing a Seq with a single element, and using Seq.++ to append two Seqs. Seq.:+ is going to be O(1) (amortized) and quite fast for an IndexedSeq. Using Seq.++ with a single-element sequence is probably still O(1), but will have a good bit more overhead.
You can start j at i instead of starting j at 0 and testing i <= j in the body of the loop. This will save n^2/2 no-op loop iterations.
Some stylistic things:
It's best to always include the return type. You actually get a deprecation warning without it.
We use lowercase for variable names in Scala
0 until size is perhaps more readable than 0 to size - 1
def getUpperTriangle(a: Array[Array[Double]]): Array[Double] = {
var result = Seq[Double]()
for (i <- 0 until a.size; j <- i until A(0).size) {
result = result :+ a(i)(j)
}
result.toArray
}

Using foldleft or some other operator to calculate point distances?

Ok so I thought this would be a snap, trying to practice Scala's collection operators and my example is a list of points.
The class can calculate and return the distance to another point (as double).
However, fold left doesn't seem to be the right solution - considering elements e1, e2, e3.. I need a moving window to calculate, I need the last element looked at to carry forward in the function - not just the sum
Sum {
e1.dist(e2)
e2.dist(e3)
etc
}
Reading the API I noticed a function called "sliding", perhaps that's the correct solution in conjunction with another operator. I know how to do this with loops of course, but trying to learn the scala way.
Thanks
import scala.math._
case class Point(x:Int, y:Int) {
def dist(p:Point) = sqrt( (p.x-x)^2+(p.y-y)^2 )
}
object Point {
//Unsure how to define this?
def dist(l:Seq[Point]) =l.foldLeft(0.0)((sum:Double,p:Point)=>)
}
I'm not quite sure what you want to do, but assuming you want the sum of the distances:
l.zip(l.tail).map { case (x,y) => x.dist(y) }.sum
Or with sliding:
l.sliding(2).map {
case List(fst,snd) => fst.dist(snd)
case _ => 0
}.sum
If you want to do it as a fold, you can, but you need the accumulator to keep both the total and the previous element:
l.foldLeft(l.head, 0.0){
case ((prev, sum), p) => (p, sum + p.dist(prev))
}._2
You finish with a tuple consiting of the last element and sum, so use ._2 to get the sum part.
btw, ^ on Int is bitwise logical XOR, not power. Use math.pow.
The smartest way is probably using zipped, which is a kind of iterator so you don't traverse the list more than once as you would using zip:
(l, l.tail).zipped.map( _ dist _ ).sum

Idiomatic form of dealing with un-initialized var

I'm coding up my first Scala script to get a feel for the language, and I'm a bit stuck as to the best way to achieve something.
My situation is the following, I have a method which I need to call N times, this method returns an Int on each run (might be different, there's a random component to the execution), and I want to keep the best run (the smallest value returned on these runs).
Now, coming from a Java/Python background, I would simply initialize the variable with null/None, and compare in the if, something like:
best = None
for...
result = executionOfThings()
if(best is None or result < best):
best = result
And that's that (pardon for the semi-python pseudo-code).
Now, on Scala, I'm struggling a bit. I've read about the usage of Option and pattern matching to achieve the same effect, and I guess I could code up something like (this was the best I could come up with):
best match {
case None => best = Some(res)
case Some(x) if x > res => best = Some(res)
case _ =>
}
I believe this works, but I'm not sure if it's the most idiomatic way of writing it. It's clear enough, but a bit verbose for such a simple "use-case".
Anyone that could shine a functional light on me?
Thanks.
For this particular problem, not in general, I would suggest initializing with Int.MaxValue as long as you're guaranteed that N >= 1. Then you just
if (result < best) best = result
You could also, with best as an option,
best = best.filter(_ >= result).orElse( Some(result) )
if the optionality is important (e.g. it is possible that N == 0, and you don't take a distinct path through the code in that case). This is a more general way to deal with optional values that may get replaced: use filter to keep the non-replaced cases, and orElse to fill in the replacement if needed.
Just use the min function:
(for (... executionOfThings()).min
Example:
((1 to 5).map (x => 4 * x * x - (x * x * x))).min
edit: adjusted to #user-unknown's suggestion
I would suggest you to rethink you whole computation to be more functional. You mutate state which should be avoided. I could think of a recursive version of your code:
def calcBest[A](xs: List[A])(f: A => Int): Int = {
def calcBest(xs: List[A], best: Int = Int.MaxValue): Int = xs match {
// will match an empty list
case Nil => best
// x will hold the head of the list and rest the rest ;-)
case x :: rest => calcBest(rest, math.min(f(x), best))
}
calcBest(xs)
}
callable with calcBest(List(7,5,3,8,2))(_*2) // => res0: Int = 4
With this you have no mutable state at all.
Another way would be to use foldLeft on the list:
list.foldLeft(Int.MaxValue) { case (best,x) => math.min(calculation(x),best) }
foldLeft takes a B and a PartialFunction of Tuple2[B,A] => B and returns B
Both ways are equivalent. The first one is probably faster, the second is more readable. Both traverse a list call a function on each value and return the smallest. Which from your snippet is what you want, right?
I thought I would offer another idiomatic solution. You can use Iterator.continually to create an infinite-length iterator that's lazily evaluated, take(N) to limit the iterator to N elements, and use min to find the winner.
Iterator.continually { executionOfThings() }.take(N).min

Dimensions of a collection, and how to traverse it in an efficient, elegant manner

I'm trying to find an elegant way to deal with multi-dimensional collections in Scala. My understanding is that I can have up to a 5 dimensional collection using tabulate, such as in the case of the following 2-Dimensional array:
val test = Array.tabulate[Double](row,col)(_+_)
and that I can access the elements of the array using
for(i<-0 until row) {
for(j<-0 until col) {
test(i)(j) = 0.0
}
}
If I don't know a priori what I'm going to be handling, what might be a succinct way of determining the structure of the collection, and spanning it, without doing something like:
case(Array(x)) =>
for(i<-1 until dim1) {
test(i) = 0.0
}
case(Array(x,y)) =>
for(i<-1 until dim1) {
for(j<-1 until dim2) {
test(i)(j) = 0.0
}
}
case(Array(x,y,z)) =>
...
The dimensional values n1, n2, n3, etc... are private, right? Also, would one use the same trick of unwrapping a 2-D array into a 1-D vector when dealing with n-Dimensional objects if I want a single case to handle the traversal?
Thanks in advance
Bruce
i would use recursion and pattern matching in this case:def doSome(a:Array[_]){
for(i <- a){
i match{
case x:Array[_] => doSome(x)
case x => println(x) // do something sensible here
}
}
}
First, some corrections:
val test = Array.tabulate[Double](row,col)(_+_)
This will produce an Array[Array[Double]], and the easiest way to zero every element is:
test foreach { inner => in.indices foreach { _ => 0.0 } }
Where you loop over each inner array contained by the outer array, and for the inner array update each element. There's no need to know the actual number of elements, nor is it desirable to do so (just imagine doing that with a parallel array!)
It would be much easier to use map, and work with the array as though it were immutable, but that seems to go against the spirit of your original request, so moving swiftly on...
As well as misunderstanding the nature of multi-dimensional arrays returned from the tabulate function (e.g. a nested array of arrays). You're also using pattern matching as though it were a Java switch statement, this isn't quite right. To match arrays of varying dimensionality, you'd want something like this:
case Array[Double] => ...
case Array[Array[Double]] => ...
But I'd advise against that approach. It wouldn't be easy to express safely in the type system, and you already know exactly what type was returned from tabulate based on the number of arguments you supplied