Compare size of 2 Arrays in Scala - arrays

If I have 2 arrays, how do I compare them and return the size of the smallest one? Here is what I mean:
val a = Array(1,2,3)
val b = Array(1,2,3,4)
is there some operator that I could call to compare the sizes of both and return 3, since Array a is smaller and has 3 elements?

scala> val a = Array(1,2,3)
a: Array[Int] = Array(1, 2, 3)
scala> val b = Array(1,2,3,4)
b: Array[Int] = Array(1, 2, 3, 4)
scala> math.min(a.length, b.length)
res0: Int = 3

A more generic approach, assuming you want to compare Sequences of the same type.
def getSmallerCollectionSize[T](a:Seq[T],b:Seq[T]) =
Math.min(a.size, b.size)

scala> val a = Array(1,2,3)
a:Array[Int] = Array(1,2,3)
scala> val b = Array(1,2,3,4)
b:Array[Int] = Array(1,2,3,4)
scala> a.size min b.size
res0: Int = 3
The size method gets the size of the Array and min is a comparator function between the two sizes. As with any function taking two parameters, you can call it by putting the function name between the parameters.
min is doing an implicit conversion (a set of methods that Scala tries to apply when it encounters an object of the wrong type being used) from Int to RichInt.

Related

Scala Multi Dimensional Array

I have the following two arrays
val a = Array(1,2)
val b = Array(0,a)
println(b(1)(0)) //'Any' does not take parameters
In the above example I can't index the value in the second array as '(0)' is not allowed. The expected result should print the value 1.
Is this possible?
Any help would be appreciated!!
The Multi-Dimensional Array is an array with more than two dimensions. In a matrix, the two dimensions are represented by rows and columns.
val a = Array(1, 2)
val b: Array[Any] = Array(0, a)
println(b(1)(0)) //'Any' does not take parameters. since b is not a valid Multi-Dimensional Array
val aa = Array(3, 4)
val c: Array[Array[Int]] = Array(aa, a) //Valid Multi-Dimensional Array
println(c(1)(0))

How to apply a 0-ary anonymous function to an array

Having an Array of Int, and a function without parameters:
scala> val a = new Array[Int](5)
a: Array[Int] = Array(0, 0, 0, 0, 0)
scala> def f(): Int = 1
f: ()Int
I want to apply the function f() to the array with map() or transform(). I tried the following approaches.
First approach
scala> a.map(f)
<console>:14: error: type mismatch;
found : () => Int
required: Int => ?
a.map(f)
^
It fails, which I don't really understand why.
Second approach
scala> a.map(x => f)
res1: Array[Int] = Array(1, 1, 1, 1, 1)
This one works. However, I'm declaring a parameter x that I don't use in the right side of =>. It seems that anonymous functions need at least one parameter.
Is it correct not to use x?
Is it even a bad functional style?
Practical example
To give an example on why one would use that. Imagine I have an array that at some moment I want to mutate to have random values:
val a = new Array[Int](5)
// ...
a.transform(x => random())
Try using underscore for ignored argument like so
a.map(_ => f)
which outputs
res0: Array[Int] = Array(1, 1, 1, 1, 1)
Just for the sake of playing with transformations:
def to1[A, B](f: () => B): A => B = (_: A) => f()
val a = new Array[Int](5)
def f(): Int = 1
a.map(to1(f))
Regarding your example, consider using fill:
val b = Array.fill[Int](a.size)(myArgLessFunc())

Scala: iteration 2d array to do operation

A newbie here.
val arr_one = Array(Array(1, 2), Array(3, 4), Array(5, 6),Array(x, y)..and so on)
val arr_two = Array(Array(2,3), Array(4, 5), Array(6, 7))
var tempArr = ArrayBuffer[Double]()
I want to multiply arr_one and arr_two. for example
Iteration1 :Array(1*2+2*3, 1*4 +2*5, 1*6+2*7 ) assign to tempArr
Iteration2 :Array(3*2+4*3, 3*4 +4*5, 3*6+4*7) assign to tempArr
Iteration3 :Array(5*2+6*3, 5*4 +6*5, 5*6+6*7) assign to tempArr
I knew that if
val x = Array(1, 2) ; val y = Array(Array(2,3), Array(4, 5), Array(6, 7))
I can use y map {x zip _ map{case(a, b) => a * b} sum}
But If x like arr_one form, I don't know how to use for loop or something else to do that.
I really have on idea.
How can I do this in scala?
Really thanks.
I believe this does what you need, without any mutable state and "iterations" - it uses the "for-comprehension" syntax which is kind of a non-imperative for-loop - in other words, instead of changing state in each iteration, it returns a value which is the sequence of results per "iteration":
val result: Array[Array[Int]] = for (arr1 <- arr_one) yield {
for (arr2 <- arr_two) yield multArrays(arr1, arr2)
}
Assuming that multArrays has the following signature:
def multArrays(arr1: Array[Int], arr2: Array[Int]): Int
That calculates the value for each cell. A naive implementation (assuming arrays have size 2) would be:
def multArrays(arr1: Array[Int], arr2: Array[Int]): Int = {
arr1(0) * arr2(0) + arr1(1) * arr2(1)
}
But of course this can be generalized to any size arrays.
May be this is what you need:
val tmp = arr_one map ((arr1) => {arr_two map (arr2 => (arr1 zip arr2) map {case(a, b) => a * b} reduce (_ + _))} )
And to get ArrayBuffer simply use :
tmpArr = tmp.toBuffer

Efficient 2 dimensional array column extraction in Scala

Consider a 2 dimensional Array, for instance
scala> val a = Array.tabulate(2,3){_+_}
a: Array[Array[Int]] = Array(Array(0, 1, 2), Array(1, 2, 3))
How to define a function
def getCol(ith: Int, a: Array[Array[Int]]): Array[Int]
that delivers
val col2 = getCol(2, a)
col2: Array[Int] = Array(1,2)
A simple and inefficient approach includes
def getCol(ith: Int, a: Array[Int]): Array[Int] = {
val t = a.transpose
t(ith)
}
Thus to ask also for more efficient ways.
def getCol(n: Int, a: Array[Array[Int]]) = a.map{_(n - 1)}
Note that you have to use n - 1 for Nth element.

strange ArrayBuffer behavior

Can someone please explain to me why the padTo method of ArrayBuffer doesn't work as I would expect it to? In this example, I would expect the array created by toArray to have a length of 10.
scala> val b = new scala.collection.mutable.ArrayBuffer[Byte]
b: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer()
scala> b.append(2)
scala> b
res1: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(2)
scala> b.append(2)
scala> b
res3: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(2, 2)
scala> b.padTo(10,0)
res4: scala.collection.mutable.ArrayBuffer[AnyVal] = ArrayBuffer(2, 2, 0, 0, 0, 0, 0, 0, 0, 0)
scala> b.toArray
res5: Array[Byte] = Array(2, 2)
Because padTo returns a new sequence (it doesn't mutate the existing one):
Try
var c = b.padTo(10,0)
c.toArray
See also: https://issues.scala-lang.org/browse/SI-2257
If you look at the documentation, you'll see the difference:
def append (elems: A*): Unit
Use case (append): Appends the given elements to this buffer.
def padTo (len: Int, elem: A): ArrayBuffer[A]
Use case (padTo): Appends an element value to this arraybuffer until a given target length is reached.
Append returns Unit, while padTo returns new ArrayBuffer.
From scaladoc:
returns: a new collection of type That consisting of all elements of
this arraybuffer followed by the minimal number of occurrences of elem
so that the resulting collection has a length of at least len.
So, b, even mutable, does not changes.

Resources