Mandroid
Mandroid

Reputation: 7524

List concatenation operations in Scala

In Scala, there are two operations available for List creation from other List objects:conc(:::) and cons(::)

::: flattens the elements from input lists.

val fruits = List("Mango","Apple","Grapes");
val veggies = List("Potato","Brinjal","Jackfruit")
val conc = fruits:::veggies

conc is List("Mango","Apple","Grapes","Potato","Brinjal","Jackfruit"). As original lists are immutable, doesn't it mean now we have duplicated data?

in case of ::, this happens:

val fruits = List("Mango","Apple","Grapes");
val veggies = List("Potato","Brinjal","Jackfruit")
val cons = fruits::veggies

cons is List(List("Mango","Apple","Grapes"),"Potato","Brinjal","Jackfruit") It seems first element in cons is merely reference to fruits, hence negligible duplication.But last three entries are again major duplication from veggies.

Upvotes: 2

Views: 1528

Answers (1)

user unknown
user unknown

Reputation: 36269

In Scala, there are two operations available for List creation from other List objects:conc(:::) and cons(::)

No.

Only the first is for creation from List objects. The cons is for creation from Objects.

Since Lists are objects themselves, you can put a List as element into another List, but in almost all cases, you don't want to do it.

scala> val fruits = List("Mango","Apple","Grapes");
fruits: List[String] = List(Mango, Apple, Grapes)

scala> val veggies = List("Potato","Brinjal","Jackfruit")
veggies: List[String] = List(Potato, Brinjal, Jackfruit)

scala> val cons = fruits::veggies
cons: List[java.io.Serializable] = List(List(Mango, Apple, Grapes), Potato, Brinjal, Jackfruit)

See, how the type of the 3rd list varies: it is a List of [java.ioSerializable], the first common ancestor of List and String, the Compiler found. And cons.size is 4, not 6: The fruit list as first element and the 3 veggies.

As original lists are immutable, doesn't it mean now we have duplicated data?

Yes (and no).

scala> val fruits = List ("Mango","Apple","Grapes");
fruits: List[String] = List(Mango, Apple, Grapes)

scala> val veggies = List ("Potato","Brinjal","Jackfruit")
veggies: List[String] = List(Potato, Brinjal, Jackfruit)

scala> val conc = fruits ::: veggies
conc: List[String] = List(Mango, Apple, Grapes, Potato, Brinjal, Jackfruit)

You get, what you asked for, and fruits is immutable, so you can't append veggies to it, so there is no way around it.

It seems first element in cons is merely reference to fruits, hence negligible duplication. But last three entries are again major duplication from veggies.

The first element is a reference to the first element of fruits, and the second element a reference the head of veggies, since both lists are immutable. But the last element of fruits, which points to Nil, can't be changed to point to the head of veggie, since this would alter fruits, which is prohibited.

However, there are mutable lists in scala.collection.mutable, which can be modified in place.

In many cases you don't need to have concerns about memory. The 3 Lists, the 2 original list and the combined are mostly links to the Strings (they don't need to store the whole String themselves, because the Strings are immutable, too), and each element has a link to the next element in the List.

Upvotes: 4

Related Questions