Efficient 2 dimensional array column extraction in Scala - arrays

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.

Related

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

In Scala, how do you convert an Array with n elements into an Array of tuples?

How do you convert from an Array[Int] of length n, into an Array[(Int,Option[Int])] of length Math.ceil(n / 2.0).toInt?
scala> val a = Array(1, 2, 3, 4)
a: Array[Int] = Array(1, 2, 3, 4)
The resultant Array for the example above would be Array((1, Some(2)), (3, some(4))). If a were Array(1), then the desired result would be Array((1, None)).
Capice?
grouped is useful for breaking the array into pairs, and case is useful for dealing with the possibility of a leftover element:
def toPairs[T](xs: Array[T]): Array[(T, Option[T])] =
xs.grouped(2)
.map{
case Array(a, b) => (a, Some(b))
case Array(a) => (a, None)
}.toArray
scala> toPairs(Array(1, 2, 3, 4, 5))
res0: Array[(Int, Option[Int])] = Array((1,Some(2)), (3,Some(4)), (5,None))
Something similar to Seth's suggestion, just a little more concise.
scala> Array(1,2,3,4,5).grouped(2).map(x=> (x.head, x.tail.headOption)).toArray
res17: Array[(Int, Option[Int])] = Array((1,Some(2)), (3,Some(4)), (5,None))

Faster way to make a zeroed array in Scala

I create zeroed Arrays in Scala with
(0 until Nrows).map (_ => 0).toArray but is there anything faster ? map is slow.
I have the same question but with 1 instead of O, i.e. I also want to accelerate (0 until Nrows).map (_ => 1).toArray
Zero is the default value for an array of Ints, so just do this:
val array = new Array[Int](NRows)
If you want all those values to be 1s then use .fill() (with thanks to #gourlaysama):
val array = Array.fill(NRows)(1)
However, looking at how this works internally, it involves the creation of a few objects that you don't need. I suspect the following (uglier) approach may be quicker if speed is your main concern:
val array = new Array[Int](NRows)
for (i <- 0 until array.length) { array(i) = 1 }
For multidimensional arrays consider Array.ofDim, for instance,
scala> val a = Array.ofDim[Int](3,3)
a: Array[Array[Int]] = Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0))
Likewise,
scala> val a = Array.ofDim[Int](3)
a: Array[Int] = Array(0, 0, 0)
In the context here,
val a = Array.ofDim[Int](NRows)
For setting (possibly nonzero) initial values, consider Array.tabulate, for instance,
scala> Array.tabulate(3,3)( (x,y) => 1)
res5: Array[Array[Int]] = Array(Array(1, 1, 1), Array(1, 1, 1), Array(1, 1, 1))
scala> Array.tabulate(3)( x => 1)
res18: Array[Int] = Array(1, 1, 1)

Compare size of 2 Arrays in Scala

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.

How to check that an array contains a particular value in Scala 2.8?

I've got an array A of D unique (int, int) tuples.
I need to know if the array contains (X, Y) value.
Am I to implement a search algorithm myself or there is a standard function for this in Scala 2.8? I've looked at documentation but couldn't find anything of such there.
That seems easy (unless I'm missing something):
scala> val A = Array((1,2),(3,4))
A: Array[(Int, Int)] = Array((1,2), (3,4))
scala> A contains (1,2)
res0: Boolean = true
scala> A contains (5,6)
res1: Boolean = false
I think the api calls you're looking for is in ArrayLike.
I found this nice way of doing
scala> var personArray = Array(("Alice", 1), ("Bob", 2), ("Carol", 3))
personArray: Array[(String, Int)] = Array((Alice,1), (Bob,2), (Carol,3))
scala> personArray.find(_ == ("Alice", 1))
res25: Option[(String, Int)] = Some((Alice,1))
scala> personArray.find(_ == ("Alic", 1))
res26: Option[(String, Int)] = None
scala> personArray.find(_ == ("Alic", 1)).getOrElse(("David", 1))
res27: (String, Int) = (David,1)

Resources