Idiom do-up collection updates

Scenario

val col: IndexedSeq[Array[Char]] = for (i <- 1 to n) yield {
   val x = for (j <- 1 to m) yield 'x'
   x.toArray
}

This is a fairly simple char matrix. toArrayused to update.

  var west = last.x - 1
  while (west >= 0 && arr(last.y)(west) == '.') {
      arr(last.y)(west) = ch;
      west -= 1;
  }

This is an update of all .until cha non-point char is found.

In general, an update to a stop state is performed, an unknown number of steps.

What is its idiomatic equivalent?

Conclusion

This is doable, but the trade-off is not worth it, much performance is lost for expressive syntax when the collection allows updates.

+4
source share
2 answers

" , " , , , . , , , "", . :

@tailrec
def update(arr:List[Char], replace:Char, replacement:Char, result:List[Char] = Nil):List[Char] = arr match {
    case `replace` :: tail =>
        update(tail, replace, replacement, replacement :: result)
    case _ => result.reverse ::: arr
}

( List , ) replace char replacement.

, :

col.map { x => update(x, '.', ch) }

- mapUntil , ( Scalaz, , - ). , , :

def mapUntil[T](input:List[T])(f:(T => Option[T])) = {
    @tailrec
    def inner(xs:List[T], result:List[T]):List[T] = xs match {
        case Nil => Nil
        case head :: tail => f(head) match {
            case None => (head :: result).reverse ::: tail
            case Some(x) => inner(tail, x :: result)
        }
    }

    inner(input, Nil)
}

, map, , , None, .

mapUntil(List(1,2,3,4)) {
    case x if x >= 3 => None
    case x => Some(x-1)
}

List[Int] = List(0, 1, 3, 4)

Scalaz, .

+3

x3ro - , . . , , API :

col.map { a =>
  val (l, r) = a.span(_ == '.')
  l.map {
    case '.' => ch
    case x => x
  } ++ r
}
+2

All Articles