読者です 読者をやめる 読者になる 読者になる

配列のかけ算と割り算

mixiscalaコミュで教えてもらった内容。すげーすっきりした。

mixi にて質問した内容

お題
1: var array1 = Array(1,2,3,4)
2: var array2 = Array(5,6,7,8)
3: var result = array1 * array2;
4: println(result)
-> Array(5, 12, 21, 32)

のようなソースを考えていて、あたりまえですがそのままだと3行目で
value * is not a member of Array[Int]
とおこられてしまいます。

var result = multi(array1 * array2)

のようにして、multiメソッド(独自メソッド)内で計算してしまえばよいのですが、このような方法ではなく、

var result = array1 * array2

のように計算させたいのですが、何か良い書き方はないでしょうか? 
回答

どんぴしゃの回答をもらった

class RichIntArray(self: Array[Int]) {
  def *(another: Array[Int]): Array[Int] = {
    assert(self.size == another.size)
    self zip another map { case (x, y) => x * y }
  }
}

implicit def extendArray(self: Array[Int]) = new RichIntArray(self)

val array1 = Array(1,2,3,4)
val array2 = Array(5,6,7,8)
val result = array1 * array2
println(result mkString ",") 
-> 5,12,21,32

応用 多重配列に応用してみる&ついでに割り算も

class RichDoubleArray2(self: Array[Array[Double]]) {
  def *(another: Array[Array[Double]]): Array[Array[Double]] = {
    assert(self.size == another.size)
    assert(self(0).size == another(0).size)
    self zip another map { case(s, a) => s zip a map {case(x, y) => x * y}}
  }
  def /(another: Array[Array[Double]]): Array[Array[Double]] = {
    assert(self.size == another.size)
    assert(self(0).size == another(0).size)
    // self zip another map { case(s, a) => s zip a map {case(x, y) => x / y}}
    self zip another map { case(s, a) => s zip a map {case(x, y) => 
      y match {
        case 0 => 0
        case _ => x / y
      }
    }}
  }
} 

implicit def extendArray2(self: Array[Array[Double]]) = new RichDoubleArray2(self)

val array3 = Array(Array(1.0,2.0,3.0),Array(4.0,5.0,6.0))
val array4 = Array(Array(2.0,2.0,2.0),Array(3.0,3.0,3.0))
val rtn1 = array3 * array4
-> [[2.0, 4.0, 6.0], [12.0, 15.0, 18.0]]
val rtn2 = array3 / array4
-> [[0.5, 1.0, 1.5], [1.3333333333333333, 1.6666666666666667, 2.0]]