string s = "ABCDEFGH";
s= s.Remove(3, 2).Insert(3, "ZX");
Ниже приводится функциональная версия обмена со следующим элементом в списке, вы просто создаете новый список с замененными элементами.
def swapWithNext[T](l: List[T], e : T) : List[T] = l match {
case Nil => Nil
case `e`::next::tl => next::e::tl
case hd::tl => hd::swapWithNext(tl, e)
}
Альтернативная реализация метода венечки:
def swapWithNext[T](l: List[T], e: T): List[T] = {
val (h,t) = l.span(_ != e)
h ::: t.tail.head :: e :: t.tail.tail
}
Обратите внимание, что это не срабатывает с ошибкой, если e - последний элемент.
Если вы знаете оба элемента, и каждый элемент встречается только один раз, он становится более элегантным:
def swap[T](l: List[T], a:T, b:T) : List[T] = l.map(_ match {
case `a` => b
case `b` => a
case e => e }
)
Застежка-молния - это чисто функциональная структура данных с указателем на эту структуру. Другими словами, это элемент с контекстом в некоторой структуре.
Например, библиотека Scalaz предоставляет класс Zipper
, который моделирует список с определенным элементом списка в фокусе.
Вы можете получить застежку-молнию для списка, ориентированного на первый элемент.
import scalaz._
import Scalaz._
val z: Option[Zipper[Int]] = List(1,2,3,4).toZipper
Вы можете переместить фокус молнии, используя методы на Застежка-молния
, например, вы можете перейти к следующему смещению от текущего фокуса.
val z2: Option[Zipper[Int]] = z >>= (_.next)
Это похоже на List.tail
, за исключением того, что он запоминает, где был.
Затем, когда выбранный вами элемент окажется в фокусе, вы можете изменить элементы вокруг фокуса.
val swappedWithNext: Option[Zipper[Int]] =
for (x <- z2;
y <- x.delete)
yield y.insertLeft(x.focus)
Примечание: это последняя версия заголовка ствола Scalaz, в которой исправлена ошибка хвостовой рекурсии find
и move
Зиппера.
Тогда вам нужен простой метод:
def swapWithNext[T](l: List[T], p: T => Boolean) : List[T] = (for {
z <- l.toZipper
y <- z.findZ(p)
x <- y.delete
} yield x.insertLeft(y.focus).toStream.toList) getOrElse l
Соответствует элементу, основанному на предикате p
. Но вы можете пойти дальше и рассмотреть все близлежащие элементы. Например, чтобы реализовать сортировку вставкой.
Общая версия Landei:
import scala.collection.generic.CanBuildFrom
import scala.collection.SeqLike
def swapWithNext[A,CC](cc: CC, e: A)(implicit w1: CC => SeqLike[A,CC],
w2: CanBuildFrom[CC,A,CC]): CC = {
val seq: SeqLike[A,CC] = cc
val (h,t) = seq.span(_ != e)
val (m,l) = (t.head,t.tail)
if(l.isEmpty) cc
else (h :+ l.head :+ m) ++ l.tail
}
некоторые виды использования :
scala> swapWithNext(List(1,2,3,4),3)
res0: List[Int] = List(1, 2, 4, 3)
scala> swapWithNext("abcdef",'d')
res2: java.lang.String = abcedf
scala> swapWithNext(Array(1,2,3,4,5),2)
res3: Array[Int] = Array(1, 3, 2, 4, 5)
scala> swapWithNext(Seq(1,2,3,4),3)
res4: Seq[Int] = List(1, 2, 4, 3)
scala>