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
}
3
  • Check contravariance and covariance: docs.scala-lang.org/tour/variances.html Commented May 14, 2020 at 6:51
  • 1
    Here it's more about type constraints, eg. [T: Numeric] Commented May 14, 2020 at 7:03
  • 1
    @Sid Variance applies to classes not methods so it has nothing to do with this. Commented May 14, 2020 at 8:00

2 Answers 2

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Thank jwvh, this almost solve my problem. I know it is trick for returnning Array[T].
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 for more details on the subject.
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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.