Scalatest Matcher - Check single value exists in a set of values - scala

I am generating a value, and I know the possible values it could be. I want to write this
val myInt = someFunction()
myInt shouldBe oneOf (1, 2, 3)
However this doesn't seem to work for me as of Scalatest 3 M15. My workaround is
List(myValue) should contain atMostOneOf (1, 2, 3)
Which is a lot more confusing to read and understand.
Is there a way to do what I want here? It seems like a common scenario.

oneOf can only be used to compare contents of collections. You can use Some as a simple one-element collection:
Some(myInt) should contain oneOf (1, 2, 3)
Alternatively:
myInt should (equal(1) or equal(2) or equal(3))

Related

Order in Scala set

I noticed, when Scala Set has less than 5 elements, it maintains order. But it doesn't maintain order after that. Just curious to know the reason behind it.
Note - I am not depending on the order of elements in a Set. This is an observation and curious to know if this is a correct observation and how is this happening.
Code example:
val s= Set(4,3,1)
println(s)
val s1= Set(4,3,1,2)
println(s1)
val s2= Set(4,3,1,2,5)
println(s2)
Output:
Set(4, 3, 1)
Set(4, 3, 1, 2)
Set(5, 1, 2, 3, 4)
Looking at the Scala 2.13 implementation for immutable Set it appears the code has special case class implementations for sets up to size 4.

How to create an Array[Any] containing integer values in scala?

Update:
I had misunderstood an error message, so this question is invalid.
val inputIds = Array[Any](7, 1, 3)
is sufficient to create an Array[Any] in Scala.
===========
I'm trying to create an array that needs to be passed to a method that takes an Array[Any], but the values are numeric.
At first I tried just the normal way of creating an array:
val inputIds = Array(7, 1, 4)
and got the error:
Type mismatch, expected: Array[Any], actual: Array[Int]
(from the IntelliJ editor, I guess I haven't checked if it's correct)
Then I tried creating Integer values directly, e.g. by:
Integer.getInteger("7")
and passing those into the Array constructor, but I kept getting the same error.
Now I tried:
val inputIds: Array[Any] = Array[Any](7, 1, 4)
and it gave me:
Type mismatch, expected: Array[Any], actual: Array[Array[Int]]
As you can tell I'm going a bit spare, all I want is wrapper types and not primitives! I guess Scala is trying to optimize the array for iteration, but all I need is a tiny array I can pass to a var args taking arrays of mixed type.. Or maybe a better way of creating that vararg method?? Right now its type is:
Array[Any]*
========
Okay, so I got my original question resolved (though there's still a dispute in the comments over whether I correctly understood why the error was being caused). However, it didn't solve my problem, which is the following:
I am trying to transpose an array of arrays with different types (some are nested, but ultimately either Double or Ints) and can't figure out how to get the scala type system to do it. Here's the basic example:
val integerArray = Array(7, 1, 4)
val nestedIntegerArray = Array(
Array(6, 10, 60),
Array(5, 89, 57),
Array(15, 3, 5)
)
val nestedDoubleArray = Array(
Array(.13, .9, .8),
Array(.2, .777, .57),
Array(.15, .3, .5)
)
val brokenComputation = typeErrorExample(integerArray, nestedIntegerArray, nestedDoubleArray)
where the method being called is:
private def typeErrorExample(arrays: Array[_ <: Any]*)={
val arrayDataFrame = Array(arrays).transpose
}
This gives the error:
No implicit view available from Seq[Array[_]] => Array[U].
[INFO] val arrayDataFrame = Array(arrays).transpose
What's the right way to do this? Should I use a non-array data structure instead?
Hopefully having more of the code will help the experts understand what was causing my original error too. (inputIds was renamed to integerArray for consistency).
Explicitly casting is not ideal, but should do the trick.
Array(1, 2, 3).asInstanceOf[Array[Any]]
#Adair, this appears to arrange the input arrays into the Array[Array[Any]] type that you're looking for.
def transpose(arrays: Array[_]*) :Array[Array[_]] =
arrays.indices.map(x => arrays.map(_(x)).toArray).toArray
Now here's a word of advice: DON'T DO IT.
It's unsafe. This will throw an exception if the number of arrays passed exceeds the dimensions of each array.
Type Any is not what you want. When a data element becomes type Any then you've lost type information and it's a royal pain trying to get it back.
Jason's answer works, so does doing what the compiler error suggests when I ran it outside of intelliJ and changing the datatype in the method signature:
arrays: Array[_ <: Any]*
scala> Array(1, 2, 3).map(_.asInstanceOf[Any])
res6: Array[Any] = Array(1, 2, 3)
There are many answers which are correct. But why even need to do asInstanceOf. You can do it easily.
scala> val arr: Array[Any] = Array(1,2,3)
arr: Array[Any] = Array(1, 2, 3)
Simple, Work is done.

The easiest way to write {1, 2, 4, 8, 16 } in Scala

I was advertising Scala to a friend (who uses Java most of the time) and he asked me a challenge: what's the way to write an array {1, 2, 4, 8, 16} in Scala.
I don't know functional programming that well, but I really like Scala. However, this is a iterative array formed by (n*(n-1)), but how to keep track of the previous step? Is there a way to do it easily in Scala or do I have to write more than one line of code to achieve this?
Array.iterate(1, 5)(2 * _)
or
Array.iterate(1, 5)(n => 2 * n)
Elaborating on this as asked for in comment. Don't know what you want me to elaborate on, hope you will find what you need.
This is the function iterate(start,len)(f) on object Array (scaladoc). That would be a static in java.
The point is to fill an array of len elements, from first value start and always computing the next element by passing the previous one to function f.
A basic implementation would be
import scala.reflect.ClassTag
def iterate[A: ClassTag](start: A, len: Int)(f: A => A): Array[A] = {
val result = new Array[A](len)
if (len > 0) {
var current = start
result(0) = current
for (i <- 1 until len) {
current = f(current)
result(i) = current
}
}
result
}
(the actual implementation, not much different can be found here. It is a little different mostly because the same code is used for different data structures, e.g List.iterate)
Beside that, the implementation is very straightforward . The syntax may need some explanations :
def iterate[A](...) : Array[A] makes it a generic methods, usable for any type A. That would be public <A> A[] iterate(...) in java.
ClassTag is just a technicality, in scala as in java, you normally cannot create an array of a generic type (java new E[]), and the : ClassTag asks the compiler to add some magic which is very similar to adding at method declaration, and passing at call site, a class<A> clazz parameter in java, which can then be used to create the array by reflection. If you do e.g List.iterate rather than Array.iterate, it is not needed.
Maybe more surprising, the two parameters lists, one with start and len, and then in a separate parentheses, the one with f. Scala allows a method to have severals parameters lists. Here the reason is the peculiar way scala does type inference : Looking at the first parameter list, it will determine what is A, based on the type of start. Only afterwards, it will look at the second list, and then it knows what type A is. Otherwise, it would need to be told, so if there had been only one parameter list, def iterate[A: ClassTag](start: A, len: Int, f: A => A),
then the call should be either
Array.iterate(1, 5, n : Int => 2 * n)
Array.iterate[Int](1, 5, n => 2 * n)
Array.iterate(1, 5, 2 * (_: int))
Array.iterate[Int](1, 5, 2 * _)
making Int explicit one way or another. So it is common in scala to put function arguments in a separate argument list. The type might be much longer to write than just 'Int'.
A => A is just syntactic sugar for type Function1[A,A]. Obviously a functional language has functions as (first class) values, and a typed functional language has types for functions.
In the call, iterate(1, 5)(n => 2 * n), n => 2 * n is the value of the function. A more complete declaration would be {n: Int => 2 * n}, but one may dispense with Int for the reason stated above. Scala syntax is rather flexible, one may also dispense with either the parentheses or the brackets. So it could be iterate(1, 5){n => 2 * n}. The curlies allow a full block with several instruction, not needed here.
As for immutability, Array is basically mutable, there is no way to put a value in an array except to change the array at some point. My implementation (and the one in the library) also use a mutable var (current) and a side-effecting for, which is not strictly necessary, a (tail-)recursive implementation would be only a little longer to write, and just as efficient. But a mutable local does not hurt much, and we are already dealing with a mutable array anyway.
always more than one way to do it in Scala:
scala> (0 until 5).map(1<<_).toArray
res48: Array[Int] = Array(1, 2, 4, 8, 16)
or
scala> (for (i <- 0 to 4) yield 1<<i).toArray
res49: Array[Int] = Array(1, 2, 4, 8, 16)
or even
scala> List.fill(4)(1).scanLeft(1)(2*_+0*_).toArray
res61: Array[Int] = Array(1, 2, 4, 8, 16)
The other answers are fine if you happen to know in advance how many entries will be in the resulting list. But if you want to take all of the entries up to some limit, you should create an Iterator, use takeWhile to get the prefix you want, and create an array from that, like so:
scala> Iterator.iterate(1)(2*_).takeWhile(_<=16).toArray
res21: Array[Int] = Array(1, 2, 4, 8, 16)
It all boils down to whether what you really want is more correctly stated as
the first 5 powers of 2 starting at 1, or
the powers of 2 from 1 to 16
For non-trivial functions you almost always want to specify the end condition and let the program figure out how many entries there are. Of course your example was simple, and in fact the real easiest way to create that simple array is just to write it out literally:
scala> Array(1,2,4,8,16)
res22: Array[Int] = Array(1, 2, 4, 8, 16)
But presumably you were asking for a general technique you could use for arbitrarily complex problems. For that, Iterator and takeWhile are generally the tools you need.
You don't have to keep track of the previous step. Also, each element is not formed by n * (n - 1). You probably meant f(n) = f(n - 1) * 2.
Anyway, to answer your question, here's how you do it:
(0 until 5).map(math.pow(2, _).toInt).toArray

Should Scala's map() behave differently when mapping to the same type?

In the Scala Collections framework, I think there are some behaviors that are counterintuitive when using map().
We can distinguish two kinds of transformations on (immutable) collections. Those whose implementation calls newBuilder to recreate the resulting collection, and those who go though an implicit CanBuildFrom to obtain the builder.
The first category contains all transformations where the type of the contained elements does not change. They are, for example, filter, partition, drop, take, span, etc. These transformations are free to call newBuilder and to recreate the same collection type as the one they are called on, no matter how specific: filtering a List[Int] can always return a List[Int]; filtering a BitSet (or the RNA example structure described in this article on the architecture of the collections framework) can always return another BitSet (or RNA). Let's call them the filtering transformations.
The second category of transformations need CanBuildFroms to be more flexible, as the type of the contained elements may change, and as a result of this, the type of the collection itself maybe cannot be reused: a BitSet cannot contain Strings; an RNA contains only Bases. Examples of such transformations are map, flatMap, collect, scanLeft, ++, etc. Let's call them the mapping transformations.
Now here's the main issue to discuss. No matter what the static type of the collection is, all filtering transformations will return the same collection type, while the collection type returned by a mapping operation can vary depending on the static type.
scala> import collection.immutable.TreeSet
import collection.immutable.TreeSet
scala> val treeset = TreeSet(1,2,3,4,5) // static type == dynamic type
treeset: scala.collection.immutable.TreeSet[Int] = TreeSet(1, 2, 3, 4, 5)
scala> val set: Set[Int] = TreeSet(1,2,3,4,5) // static type != dynamic type
set: Set[Int] = TreeSet(1, 2, 3, 4, 5)
scala> treeset.filter(_ % 2 == 0)
res0: scala.collection.immutable.TreeSet[Int] = TreeSet(2, 4) // fine, a TreeSet again
scala> set.filter(_ % 2 == 0)
res1: scala.collection.immutable.Set[Int] = TreeSet(2, 4) // fine
scala> treeset.map(_ + 1)
res2: scala.collection.immutable.SortedSet[Int] = TreeSet(2, 3, 4, 5, 6) // still fine
scala> set.map(_ + 1)
res3: scala.collection.immutable.Set[Int] = Set(4, 5, 6, 2, 3) // uh?!
Now, I understand why this works like this. It is explained there and there. In short: the implicit CanBuildFrom is inserted based on the static type, and, depending on the implementation of its def apply(from: Coll) method, may or may not be able to recreate the same collection type.
Now my only point is, when we know that we are using a mapping operation yielding a collection with the same element type (which the compiler can statically determine), we could mimic the way the filtering transformations work and use the collection's native builder. We can reuse BitSet when mapping to Ints, create a new TreeSet with the same ordering, etc.
Then we would avoid cases where
for (i <- set) {
val x = i + 1
println(x)
}
does not print the incremented elements of the TreeSet in the same order as
for (i <- set; x = i + 1)
println(x)
So:
Do you think this would be a good idea to change the behavior of the mapping transformations as described?
What are the inevitable caveats I have grossly overlooked?
How could it be implemented?
I was thinking about something like an implicit sameTypeEvidence: A =:= B parameter, maybe with a default value of null (or rather an implicit canReuseCalleeBuilderEvidence: B <:< A = null), which could be used at runtime to give more information to the CanBuildFrom, which in turn could be used to determine the type of builder to return.
I looked again at it, and I think your problem doesn't arise from a particular deficiency of Scala collections, but rather a missing builder for TreeSet. Because the following does work as intended:
val list = List(1,2,3,4,5)
val seq1: Seq[Int] = list
seq1.map( _ + 1 ) // yields List
val vector = Vector(1,2,3,4,5)
val seq2: Seq[Int] = vector
seq2.map( _ + 1 ) // yields Vector
So the reason is that TreeSet is missing a specialised companion object/builder:
seq1.companion.newBuilder[Int] // ListBuffer
seq2.companion.newBuilder[Int] // VectorBuilder
treeset.companion.newBuilder[Int] // Set (oops!)
So my guess is, if you take proper provision for such a companion for your RNA class, you may find that both map and filter work as you wish...?

Get item in the list in Scala?

How in the world do you get just an element at index i from the List in scala?
I tried get(i), and [i] - nothing works. Googling only returns how to "find" an element in the list. But I already know the index of the element!
Here is the code that does not compile:
def buildTree(data: List[Data2D]):Node ={
if(data.length == 1){
var point:Data2D = data[0] //Nope - does not work
}
return null
}
Looking at the List api does not help, as my eyes just cross.
Use parentheses:
data(2)
But you don't really want to do that with lists very often, since linked lists take time to traverse. If you want to index into a collection, use Vector (immutable) or ArrayBuffer (mutable) or possibly Array (which is just a Java array, except again you index into it with (i) instead of [i]).
Safer is to use lift so you can extract the value if it exists and fail gracefully if it does not.
data.lift(2)
This will return None if the list isn't long enough to provide that element, and Some(value) if it is.
scala> val l = List("a", "b", "c")
scala> l.lift(1)
Some("b")
scala> l.lift(5)
None
Whenever you're performing an operation that may fail in this way it's great to use an Option and get the type system to help make sure you are handling the case where the element doesn't exist.
Explanation:
This works because List's apply (which sugars to just parentheses, e.g. l(index)) is like a partial function that is defined wherever the list has an element. The List.lift method turns the partial apply function (a function that is only defined for some inputs) into a normal function (defined for any input) by basically wrapping the result in an Option.
Why parentheses?
Here is the quote from the book programming in scala.
Another important idea illustrated by this example will give you insight into why arrays are accessed with parentheses in Scala. Scala has fewer special cases than Java. Arrays are simply instances of classes like any other class in Scala. When you apply parentheses surrounding one or more values to a variable, Scala will transform the code into an invocation of a method named apply on that variable. So greetStrings(i) gets transformed into greetStrings.apply(i). Thus accessing an element of an array in Scala is simply a method call like any other. This principle is not restricted to arrays: any application of an object to some arguments in parentheses will be transformed to an apply method call. Of course this will compile only if that type of object actually defines an apply method. So it's not a special case; it's a general rule.
Here are a few examples how to pull certain element (first elem in this case) using functional programming style.
// Create a multdimension Array
scala> val a = Array.ofDim[String](2, 3)
a: Array[Array[String]] = Array(Array(null, null, null), Array(null, null, null))
scala> a(0) = Array("1","2","3")
scala> a(1) = Array("4", "5", "6")
scala> a
Array[Array[String]] = Array(Array(1, 2, 3), Array(4, 5, 6))
// 1. paratheses
scala> a.map(_(0))
Array[String] = Array(1, 4)
// 2. apply
scala> a.map(_.apply(0))
Array[String] = Array(1, 4)
// 3. function literal
scala> a.map(a => a(0))
Array[String] = Array(1, 4)
// 4. lift
scala> a.map(_.lift(0))
Array[Option[String]] = Array(Some(1), Some(4))
// 5. head or last
scala> a.map(_.head)
Array[String] = Array(1, 4)
Please use parentheses () to access the list of elements, as shown below.
list_name(index)