Why map function in scala not reading Arrays [duplicate] - scala

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

Related

Filter array of tuple with an array of Double SCALA

I am very new to scala. Here is my issue:
I have an array:
val numbers = Array(1, 2, 3, 4, 5)
And an array of tupples.
val arrayTuple= Array((1,2),(10,5),(40,5),(3,4))
I would like to filter this list and keep only tuples that have their first elment in the list numbers.
val filtered=arrayTuple.filter(numbers.contains(_.1)).map(x=>x)
But it doesn't work. Can you help me please. Thank you
Your syntax to access the first element of a tuple is wrong (see the Scaladoc). You also don't need the map:
val filtered = arrayTuple.filter(t => numbers.contains(t._1))

Scala - List Variable outside of foreach loop [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
The code below isn't giving me the desired output. I am getting the output of finallist as individual characters separated by commas; I was expecting lists with two values only (filename, sizeofcolumn).
val pathurl="adl://*****.azuredatalakestore.net/<folder>/<sub_folder>"
val filelist=dbutils.fs.ls(pathurl)
val newdf = df.select("path").rdd.map(r => r(0)).collect.toList
var finallist = scala.collection.mutable.ListBuffer.empty[Any]
newdf.foreach(f => {
val MasterPq = spark.read.option("header","true").option("inferSchema","true").parquet(f.toString())
val size = MasterPq.columns.length
val mergedlist = List(f.toString(), size.toString())
mergedlist.map((x => {finallist = finallist ++ x}))
})
println(finallist)
The bug in your code is that you're using the ++ method to append values to your list. This method is used to append two list.
scala> List(1, 2) ++ List(3, 4)
res0: List[Int] = List(1, 2, 3, 4)
In scala strings are viewn as a list of characters, so your appending each individual character to your list.
scala> List(1, 2) ++ "Hello"
res3: List[AnyVal] = List(1, 2, H, e, l, l, o)
Since you're using a mutable list, you can append values with the '+=' method. If you just want to get your code working, than the following should be enough, but it is not a good solution.
// mergedlist.map((x => {finallist = finallist ++ x}))
mergedlist.map((x => finallist += x}))
You're probably new to scala, coming from a imperative language like Java. Scala collections do not work as you're known from such programming languages. Scala's collections are immutable by default. Instead of modifying collections, you're using using functions such as map to build new lists based on the old list.
The map function is one of the most used functions on lists. It takes an anonymous function as parameter that takes one element and transforms it to another value. This function is applied onto all methods of the list thereby build a new list. Here's an example:
scala> val list = List(1, 2, 3).map(i => i * 2)
list: List[Int] = List(2, 4, 6)
In this example, a function that multiplies integers by two is applied onto each element in the list. The results are put into the new list. Maybe this illustration helps to comprehend the process:
List(1, 2, 3)
| | |
* 2 * 2 * 2
↓ ↓ ↓
List(2, 4, 6)
We could use the map function to solve your task.
We can use it to map each element in the newdf list into a tuple with the corresponding (filename, filesize).
val finallist = newdf.map { f =>
val masterPq = spark.read.option("header","true").option("inferSchema","true").parquet(f.toString())
val size = masterPq.columns.length
(f.toString(), size.toString())
}
I think this code is shorter, simpler, easier to read and just way more beautiful. I will definitely recommend you to learn more about Scala's collections and immutable collections in general. Once you understand them, you'll just love them!

How to print array values in Scala? I am getting different values

Code:
object Permutations extends App
{
val ar=Array(1,2,3).combinations(2).foreach(println(_))
}
Output:
[I#378fd1ac
[I#49097b5d
[I#6e2c634b
I am trying to execute this but I am getting some other values.
How to print array values in Scala? Can any one help to print?
Use mkString
object Permutations extends App {
Array(1,2,3).combinations(2).foreach(x => println(x.mkString(", ")))
}
Scala REPL
scala> Array(1,2,3).combinations(2).foreach(x => println(x.mkString(", ")))
1, 2
1, 3
2, 3
When array instance is directly used for inside println. The toString method of array gets called and results in output like [I#49097b5d. So, use mkString for converting array instance to string.
Scala REPL
scala> println(Array(1, 2))
[I#2aadeb31
scala> Array(1, 2).mkString
res12: String = 12
scala> Array(1, 2).mkString(" ")
res13: String = 1 2
scala>
You can't print array directly, If you will try to print it will print the reference of that array.
You are almost there, Just iterate over array of array and then on individual array and display the elements like below
Array(1,2,3).combinations(2).foreach(_.foreach(println))
Or Just convert each array to string and display like below
Array(1,2,3).combinations(2).foreach(x=>println(x.mkString(" ")))
I hope this will help you

Can Lazy modify elements in Array in Scala?

I want to define an array, each element of array is a data set read from certain path in the file system, because the data reading is costly and the position in array to be visited is sparse, so I want to use Lazy modifier to realize that one data set will not be read until being visited. How can define this kind of array?
Yes,we can define it with view function.
Instead of (0 to 10).toArray
scala> val a=(0 to 10).toArray
a: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
View can not instantiate the array but when ever we call then only it executes
val a=(0 to 10).view
a: scala.collection.SeqView[Int,scala.collection.immutable.IndexedSeq[Int]] = SeqView(...)
scala> for (x <- a ){
| println(x)}
0
1
2
3
4
5
6
7
8
9
10
I hope this answered your question
No, you cannot use lazy on the array to make the elements lazy. The most natural thing to do would be to use a caching library like ScalaCache.
You can also make a kind of wrapper class with a lazy field as you suggested in your comment. However, I would prefer not to expose the caching to the clients of the array. You should be able to just write myArray(index) to access an element.
If you don't want to use a library, this is another option (without lazy) that gives you an array like object with caching:
class CachingArray[A](size: Int, getElement: Int => A) {
val elements = scala.collection.mutable.Map[Int, A]()
def apply(index: Int) = elements.getOrElseUpdate(index, getElement(index))
}
Just initialize it with the size and a function that computes an element at a given index.
If you like, you can make it extend IndexedSeq[A] so it can be used more like a real array. Just implement length like this:
override def length: Int = size

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)