Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy elements from one list to another in Scala

Tags:

list

copy

scala

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.

like image 928
Paul Avatar asked Dec 04 '22 01:12

Paul


2 Answers

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)
like image 148
senia Avatar answered Jan 05 '23 01:01

senia


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/

like image 20
Mixabuben Avatar answered Jan 05 '23 01:01

Mixabuben