I'm would like to create generic (invariant) method in Scala which copies elements from source list to destination list. In Java there is copy method in java.util.Collections (see http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#copy%28java.util.List,%20java.util.List%29). I know in Scala List is immutable object so i would like to create and return new list.
I've written the following code:
def copy[T](dest:List[T], src:List[T]):List[T] = {
if(dest.length<src.length) throw new Exception("IndexOutOfBoundsException")
else if(src==Nil) dest
else {
var ret = dest
ret = dest.updated(0, src.first)
var i=1
val f:(T=>Unit) = a => {
if(i<src.length) ret=ret.updated(i, src(i))
i+=1
()
}
dest.foreach(f)
ret
}
}
But I think it could be written better. Could you help me to write better code? Thanks in advance.
EDITED: Maybe I expressed unclear what I want to do. I have two lists (scala.collection.immutable.List), e.g. src (length=x) and dest(length=y>=x). I would like to replace first x elements of dest list with elements from src list.
Do you mean scala.collection.immutable.List
? It is immutable. No need to copy them. Immutable means that nothing can change it, so you can use it in different threads.
Generic way of creating collections in scala is builder. You can get one from CanBuildFrom
object. Alternatively you can get it from genericBuilder
method of collection instance.
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> val b = list.genericBuilder[Int]
b: scala.collection.mutable.Builder[Int,List[Int]] = ListBuffer()
scala> list.foreach{ b += _ }
scala> val result = b.result // this code is useless. `val result = list` is enough
result: List[Int] = List(1, 2, 3)
If you want to create new collection of different type based on existing collection, you can use collection.breakOut
methid like this:
scala> val list = List('a', 'b', 'c')
list: List[Char] = List(a, b, c)
scala> val result: String = list.map{identity}(collection.breakOut)
result: String = abc
Upd
require(src.length <= dest.length, "IndexOutOfBoundsException")
src ++ dest.drop(src.length)
If you want to get an updated list you can use map on your list. Map works by applying a function to each element in the list, and returning updated list.
http://www.brunton-spall.co.uk/post/2011/12/02/map-map-and-flatmap-in-scala/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With