All Downloads are FREE. Search and download functionalities are using the official Maven repository.

geotrellis.logic.ForEach.scala Maven / Gradle / Ivy

The newest version!
package geotrellis.logic

import scala.{PartialFunction => PF}
import geotrellis._

object ForEach {
  def apply[A, Z:Manifest](a:Op[Array[A]])(f:(A) => Op[Z]) = ForEach1(a)(f)
  def apply[A, B, Z:Manifest](a:Op[Array[A]], b:Op[Array[B]])(f:(A, B) => Op[Z]) = ForEach2(a, b)(f)
  def apply[A, B, C, Z:Manifest](a:Op[Array[A]], b:Op[Array[B]], c:Op[Array[C]])(f:(A, B, C) => Op[Z]) = ForEach3(a, b, c)(f)
}

/**
 * Evaluates the given operation (op) to get an array of A's. Then, applies
 * the given function (f) to each item in the array in. The resulting array of
 * Z's is returned.
 */
case class ForEach1[A, Z:Manifest](op:Op[Array[A]])(f:(A) => Op[Z]) extends Op[Array[Z]] {

  def _run() = runAsync(List(op))

  val nextSteps:PF[Any, StepOutput[Array[Z]]] = {
    case (as:Array[_]) :: Nil => {
      step2(as.asInstanceOf[Array[A]])
    }

    case zs:List[_] => Result(zs.asInstanceOf[List[Z]].toArray)
  }

  def step2(as:Array[A]) = {
    runAsync(as.toList.map(a => f(a)))
  }
}


/**
 * Evaluates the given operations (opA and opB) to get an array of A's and an
 * array of B's. Then, applies the given function (f) to each (A, B) item in
 * the arrays (pairwise by array index) to get a Z value. The resulting array
 * of Z's is returned.
 */
case class ForEach2[A, B, Z:Manifest](opA:Op[Array[A]], opB:Op[Array[B]])
                                     (f:(A, B) => Op[Z]) extends Op[Array[Z]] {

  def _run() = runAsync(List(opA, opB))

  val nextSteps:PF[Any, StepOutput[Array[Z]]] = {
    case (as:Array[_]) :: (bs:Array[_]) :: Nil => {
      step2(as.asInstanceOf[Array[A]],
            bs.asInstanceOf[Array[B]])
    }

    case zs:List[_] => Result(zs.asInstanceOf[List[Z]].toArray)
  }

  def step2(as:Array[A], bs:Array[B]) = {
    runAsync((0 until as.length).map(i => f(as(i), bs(i))).toList)
  }
}


/**
 * Evaluates the given operations (opA opB, and opC) to get arrays of A's, B's
 * and C's (which should be the same length).
 *
 * Then, applies the given function (f) to each (A, B, C) triple in (grouped by
 * array index) to get a Z value. The resulting array of Z's is returned.
 */
case class ForEach3[A, B, C, Z:Manifest](opA:Op[Array[A]],
                                         opB:Op[Array[B]],
                                         opC:Op[Array[C]])
(f:(A, B, C) => Op[Z]) extends Op[Array[Z]] {

  def _run() = runAsync(List(opA, opB, opC))

  val nextSteps:PF[Any, StepOutput[Array[Z]]] = {
    case (as:Array[_]) :: (bs:Array[_]) :: (cs:Array[_]) :: Nil => {
      step2(as.asInstanceOf[Array[A]],
            bs.asInstanceOf[Array[B]],
            cs.asInstanceOf[Array[C]])
    }

    case zs:List[_] => Result(zs.asInstanceOf[List[Z]].toArray)
  }

  def step2(as:Array[A], bs:Array[B], cs:Array[C]) = {
    runAsync((0 until as.length).toList.map(i => f(as(i), bs(i), cs(i))))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy