scala - Patch Seq using Queue -
i'm writing simulation number of operators take work single queue. @ each time step need sequentially check elements of sequence, , if condition passes replace current value item queue. remains in queue must retained later iterations.
i've written routine called patch
this, doesn't seem neat. there more idiomatic way achieve same thing? i'd fast still functional in style.
import scala.annotation.tailrec import scala.collection.immutable.queue object seqpimp extends app{ val myseq = seq('a', 'b', 'c', 'd', 'e') val shortq = queue('+','-') val longq = queue('+','-','*','/','%') println(patch(myseq)(_.isupper, shortq)) //output: (list(a, +, -, d, e),queue()) println(patch(myseq)(_.isupper, longq)) //output: (list(a, +, -, d, *),queue(/, %)) def patch[t](to: seq[t])(condition: t => boolean, from: queue[t]): (seq[t], queue[t]) = { @tailrec def go(acc: seq[t], remaining: seq[t], q: queue[t]): (seq[t], queue[t]) = { if(acc.size == to.size) (acc.reverse, q) else if(q.size == 0) (acc.reverse ++: remaining, q) else{ if(condition(remaining.head)){ val (item, q1) = q.dequeue go(item +: acc, remaining.tail, q1) }else{ go(remaining.head +: acc, remaining.tail, q) } } } go(nil, to, from) } }
prolly this...
def patch[t](to: seq[t])(condition: t => boolean, from: queue[t]): (seq[t], queue[t]) = { if (from.isempty) (to, from) else { val = to.indexwhere(condition) if (i == -1) (to, from) else patch(to.patch(i, seq(from.head), 1))(condition, from.tail) } }
or can enrich seq way..
object seqpimp extends app { implicit class enseq[t](val to: seq[t]) extends anyval{ def enpatch(condition: t => boolean, from: queue[t]): (seq[t], queue[t]) = { if (from.isempty) (to, from) else { val = to.indexwhere(condition) if (i == -1) (to, from) else to.patch(i, seq(from.head), 1).enpatch(condition, from.tail) } } } val myseq = seq('a', 'b', 'c', 'd', 'e') val shortq = queue('+', '-') val longq = queue('+', '-', '*', '/', '%') myseq.enpatch(_.isupper, shortq) //output: (list(a, +, -, d, e),queue()) myseq.enpatch(_.isupper, longq) //output: (list(a, +, -, d, *),queue(/, %)) }
edit
here def patch
better performance.. not pretty before..
def patch[t](to: seq[t])(condition: t => boolean, from: queue[t]): (seq[t], queue[t]) = { @tailrec def go(acc: seq[t], remaining: seq[t], q: queue[t]): (seq[t], queue[t]) = { if (q.isempty || remaining.isempty) (acc ++ remaining, q) else { val (accu, rem) = remaining.span(e => !condition(e)) if (rem.isempty) (acc ++ accu, q) else go(acc ++ accu.:+(q.head), rem.tail, q.tail) } } go(nil, to, from) }
Comments
Post a Comment