val list = List(4, 6, 7, 8, 9, 13, 14)
list.foreach(num ⇒ println(num * 4))
list should be()
I have tried to figure what it should be but don't quite get the answer. I think that it has to be empty or like a void function in Java but I do not know the equivalent in Scala.
void equivalent in Scala would be Unit, foreach does return Unit.
def foreach(f: (A) ⇒ Unit): Unit
So the proper (and useless) test will be this:
list should be(List(4, 6, 7, 8, 9, 13, 14))
Also take into consideration that even it the function returns something, you are not capturing it so the list will remain unchanged.
If you want to retrieve the result of a function you should assign it to another value, something like this below: (Using map to show this):
val result = list.map(num ⇒ num * 4)
result should be(List(16, 24, 28, 32, 36, 52, 56))
I don't understand what you mean by void function, but there is a way to represent empty list like this:
list should be List.empty[Int]
void in java means there is no return value, Unit in scala serves the same purpose.
When you do list.foreach then there is no return value and list is not changed (or rather the return value is Unit), instead the function is applied to each member and the return value is discarded.
I imagine you are instead looking to do a flatmap. list.flatmap(f) would apply f on each element and assume the value return from f is a collection and then flatten it. for example if list is (0, 2, 4) and f returns a list with 1 repeated the member value then f would return list(), list(1,1) and list(1, 1, 1, 1) then the returned value would be list(1,1,1,1,1,1)
In this case, just return list() to have a total return value of list().
Related
I expect the following code output with Seq(0), instead it returns a function ?
# Seq(0).orElse(Seq(1))
res2: PartialFunction[Int, Int] = <function1>
I suspected at first that via syntax sugar it orElse on apply function, but it didn't since by trying:
# Seq(0).apply.orElse(Seq(1))
cmd3.sc:1: missing argument list for method apply in trait SeqLike
....(omit)
I checked in IntellJ that there's no implicit conversion.
What happens?
EDIT:
what I wish is:
Seq.empty.orElse(Seq(1)) == Seq(1)
Seq(0).orElse(Seq(1)) == Seq(0)
thanks #AndreyTyukin answer.
In one line, orElse has different semantic in different type , now Seq inherits PartialFunction not Option, so does the orElse behavior.
The Seq(0) is treated as a PartialFunction that is defined only at index 0, and produces as result the constant value 0 if it is given the only valid input 0.
When you invoke orElse with Seq(1), a new partial function is constructed, that first tries to apply Seq(0), and if it finds nothing in the domain of definition of Seq(0), it falls back to Seq(1). Since the domain of Seq(1) is the same as the domain of Seq(0) (namely just the {0}), the orElse does essentially nothing in this case, and returns a partial function equivalent to Seq(0).
So, the result is again a partial function defined at 0 that gives 0 if it is passed the only valid input 0.
Here is a non-degenerate example with sequences of different length, which hopefully makes it easier to understand what the orElse method is for:
val f = Seq(1,2,3).orElse(Seq(10, 20, 30, 40, 50))
is a partial function:
f: PartialFunction[Int,Int] = <function1>
Here is how it maps values 0 to 4:
0 to 4 map f
// Output: Vector(1, 2, 3, 40, 50)
That is, it uses first three values from the first sequence, and falls back to the second sequence passed to orElse for inputs 3 and 4.
This also works with arbitrary partial functions, not only sequences:
scala> val g = Seq(42,43,44).orElse[Int, Int]{ case n => n * n }
g: PartialFunction[Int,Int] = <function1>
scala> 0 to 10 map g
res7 = Vector(42, 43, 44, 9, 16, 25, 36, 49, 64, 81, 100)
If you wanted to select between two sequences without treating them as partial functions, you might consider using
Option(Seq(0)).getOrElse(Seq(1))
This will return Seq(0), if this is what you wanted.
Now studying Scala and working with list of lists. Want to multiply array by an element(for example, 1).
However I get the following error:
identifier expected but integer constant found
Current code:
def multiply[A](listOfLists:List[List[A]]):List[List[A]] =
if (listOfLists == Nil) Nil
else -1 * listOfLists.head :: multiply(listOfLists.tail)
val tt = multiply[List[3,4,5,6];List[4,5,6,7,8]]
print(tt);;
There are a few issues with your code:
In general, you can't perform arithmetic on unconstrained generic types; somehow, you have to communicate any supported arithmetic operations.
Multiplying by 1 will typically have no effect anyway.
As already pointed out, you don't declare List instances using square brackets (they're used for declaring generic type arguments).
The arguments you're passing to multiply are two separate lists (using an invalid semicolon separator instead of a comma), not a list of lists.
In the if clause the return value is Nil, which matches the stated return type of List[List[A]]. However the else clause is trying to perform a calculation which is multiplying List instances (not the contents of the lists) by an Int. Even if this made sense, the resulting type is clearly not a List[List[A]]. (This also makes it difficult for me to understand exactly what it is you're trying to accomplish.)
Here's a version of your code that corrects the above, assuming that you're trying to multiply each member of the inner lists by a particular factor:
// Multiply every element in a list of lists by the specified factor, returning the
// resulting list of lists.
//
// Should work for any primitive numeric type (Int, Double, etc.). For custom value types,
// you will need to declare an `implicit val` of type Numeric[YourCustomType] with an
// appropriate implementation of the `Numeric[T]` trait. If in scope, the appropriate
// num value will be identified by the compiler and passed to the function automatically.
def multiply[A](ll: List[List[A]], factor: A)(implicit num: Numeric[A]): List[List[A]] = {
// Numeric[T] trait defines a times method that we use to perform the multiplication.
ll.map(_.map(num.times(_, factor)))
}
// Sample use: Multiply every value in the list by 5.
val tt = multiply(List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)), 5)
println(tt)
This should result in the following output:
List(List(15, 20, 25, 30), List(20, 25, 30, 35, 40))
However, it might be that you're just trying to multiply together all of the values in the lists. This is actually a little more straightforward (note the different return type):
def multiply[A](ll: List[List[A]])(implicit num: Numeric[A]): A = ll.flatten.product
// Sample use: Multiply all values in all lists together.
val tt = multiply(List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)))
println(tt)
This should result in the following output:
2419200
I'd recommend you read a good book on Scala. There's a lot of pretty sophisticated stuff going on in these examples, and it would take too long to explain it all here. A good start would be Programming in Scala, Third Edition by Odersky, Spoon & Venners. That will cover List[A] operations such as map, flatten and product as well as implicit function arguments and implicit val declarations.
To make numeric operations available to type A, you can use context bound to associate A with scala.math.Numeric which provides methods such as times and fromInt to carry out the necessary multiplication in this use case:
def multiply[A: Numeric](listOfLists: List[List[A]]): List[List[A]] = {
val num = implicitly[Numeric[A]]
import num._
if (listOfLists == Nil) Nil else
listOfLists.head.map(times(_, fromInt(-1))) :: multiply(listOfLists.tail)
}
multiply( List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)) )
// res1: List[List[Int]] = List(List(-3, -4, -5, -6), List(-4, -5, -6, -7, -8))
multiply( List(List(3.0, 4.0), List(5.0, 6.0, 7.0)) )
// res2: List[List[Double]] = List(List(-3.0, -4.0), List(-5.0, -6.0, -7.0))
For more details about context bound, here's a relevant SO link.
I have the following Scala code snippet:
(1 to 10).foreach(a => (1 to 100 by 3).toList.count(b => b % a == 0))
which, I would expect to behave like the following:
Create a list of multiple of 3 less than 100
For each item in the list previously generated, count how many multiples of 1, 2, 3... 10 there are
But, when I run the snippet, I get an empty list. What am I doing wrong?
Thanks for your help!
The behavior is totally expect when using foreach.
foreach takes a procedure — a function with a result type Unit — as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.
It's typically used for its side effects — something like printing or saving into a database, etc.
You ought using map instead :
scala> (1 to 10).map(a => (1 to 100 by 3).toList.count(b => b % a == 0))
// res3: scala.collection.immutable.IndexedSeq[Int] = Vector(34, 17, 0, 9, 7, 0, 5, 4, 0, 4)
I have a function that expects two arguments from type Set:
def union[A](set1: Set[A], set2: Set[A]): Set[A] = {
set1.foldLeft(set2){ (set, elt) => (set + elt) }
}
Apply function as follow:
union(Set(3,4,5,6), Set(34,56,23))
and I've got:
res2: Set[Int] = Set(5, 56, 6, 34, 3, 23, 4)
but I expect:
Set(3,4,5,6,34,56,23)
Why do I receive such as unordered result?
Set is an unordered data type, generally the order is determined by the implementation and is generally not guaranteed (much less guaranteed to be insertion ordered).
to get the behaviour you seem to want (distinct, insertion ordered) I would suggest using Lists and the distinct method
(List(3,4,5,6) ++ List(34,56,23)).distinct
res0: List[Int] = List(3, 4, 5, 6, 34, 56, 23)
Sets do not preserve an order - if you would like what you expect as your end result you can try this, note that it returns an ArrayBuffer (which you can then convert to what you need):
union(Set(3,4,5,6), Set(34,56,23)).toSeq.sorted
As we are dealing with a simple Ordering (Int), we don't need to specify the conditions for it to be ordered as it's implicitly done. Since your union def takes in any type, an Ordering will need to be specified based on the type you passed in. See this on guidance on creating an Ordering.
This question already has answers here:
Printing array in Scala
(7 answers)
Closed 6 years ago.
I am very new to scala programming , hence asking this question
My scala program is below
object FirstMain{
def main(args: Array[String]): Unit={
val myArray = Array(1,2,3,4)
val k =myArray.map(x => x*10)
println(k)
}
}
Why I am getting output as [I#14991ad
I want the array elements to be read and want each element to be multiplied with 10 and print the result
Also I would like to know what is the return type of map() in scala
Array is a Scala's way of representing Java arrays. Invoking Array.toString() method (which you do implicitly in println(k)) invokes toString method defined in Java's Object class (which by default prints hexadecimal representation of the hash code of the object). You should try using Scala's List type, which overrides toString() method and outputs pretty contents of the list.
val list = List(1, 2, 3, 4)
println(list) // Prints: `List(1, 2, 3, 4)`
You can also easily convert an Array to a List:
val list = Array(1, 2, 3, 4).toList
For your second question: mapping an Array returns another Array.
map builds a new collection by applying a function to all elements of this array.
To print an Array you can do the following :
val myArray = Array(1, 2, 3, 4)
// myArray: Array[Int] = Array(1, 2, 3, 4)
val k = myArray.map(x => x * 10)
// k: Array[Int] = Array(10, 20, 30, 40)
println(k.mkString("[", ",", "]"))
// [10,20,30,40]
Hence, you can read here what does actually [I#14991ad means. (Array of Integer with hashcode of the Array object 14991ad)
Array.map will return another Array
println(k) <=> println(String.valueOf(k)) <=> println(k.toString)
the Array does not override the method of toString
if you want to print your array like this Array(10, 20, 30, 40), you can use the following code
println(k.deep)
deep not in Scala 2.13 see SO answer about Array deep documentation.
Good luck with you