0

I want to calculate the mean of every two consecutive elements in array a, and return a new array. The parameter type T can be any of the numerical type such as Byte, Short, Int, Float, and Double. I don't know how to make it work. Thanks in advance!

def center[T](a: Array[T]): Array[T] = {
  for (i <- 0 until a.size - 1) yield (a(i) + a(i + 1)) / 2
}
Yvon
  • 3
  • 1

2 Answers2

1

One issue we have to deal with is that integer division produces an integer result: (2+3)/2 == 2

If we decide that we always want fractional results (maybe Double?) then it simplifies the task a bit. What's left is how to deal with input of any number type.

def center[N](a:Array[N])(implicit ev:Numeric[N]):Array[Double] = {
  import ev._
  if (a.lengthIs < 2) a.map(_.toDouble)
  else a.sliding(2)
        .map{case Array(a,b) => (a+b).toDouble/2.0}.toArray
}

testing:

center(Array(2, 3, 11, 4, 71))
//res0: Array[Double] = Array(2.5, 7.0, 7.5, 37.5)

center(Array(2.3, 1.1, 4.5, 7.1))
//res1: Array[Double] = Array(1.7, 2.8, 5.8)
jwvh
  • 50,871
  • 7
  • 38
  • 64
  • Thank jwvh, this almost solve my problem. I know it is trick for returnning Array[T]. – Yvon May 16 '20 at 06:11
  • Returning type `Array[T]` is only difficult **if** A) you want `T` to handle both fractional and integral numbers, **and** B) division is required. Integral division is a different operation than fractional division. See [this rather old question](https://stackoverflow.com/q/40351176/4993128) for more details on the subject. – jwvh May 16 '20 at 06:23
0

This code example without dividing because of you should define your own typeclass for diving by integer value.

def center[T: Numeric](a: Array[T]): Array[T] = {
  a.sliding(2).map { case Array(f, s) => Numeric[T].plus(f, s) }.toArray
}
Ivan Aristov
  • 152
  • 6