Add an item in a Seq in scala
Asked Answered
R

2

13

I am working with scala play 2 with slick. I have a Seq like

val customerList: Seq[CustomerDetail] = Seq(CustomerDetail("id", "status", "name"))

I want to add a CustomerDetail item in this customerList. How can I do this? I already tried

customerList :+ CustomerDetail("1", "Active", "Shougat")

But this doesn't do anything.

Ruggles answered 6/9, 2016 at 6:11 Comment(0)
B
10

Two things. When you use :+, the operation is left associative, meaning the element you're calling the method on should be on the left hand side.

Now, Seq (as used in your example) refers to immutable.Seq. When you append or prepend an element, it returns a new sequence containing the extra element, it doesn't add it to the existing sequence.

val newSeq = customerList :+ CustomerDetail("1", "Active", "Shougat")

But appending an element means traversing the entire list in order to add an item, consider prepending:

val newSeq = CustomerDetail("1", "Active", "Shougat") +: customerList

A simplified example:

scala> val original = Seq(1,2,3,4)
original: Seq[Int] = List(1, 2, 3, 4)

scala> val newSeq = 0 +: original
newSeq: Seq[Int] = List(0, 1, 2, 3, 4)
Bearcat answered 6/9, 2016 at 6:13 Comment(4)
you say Seq is immutable (and it probably is) but it doesn't have to be.Boswell
The concrete implementation may not be mutable, true. But the abstraction on Seq itself only exposes immutable properties.Bearcat
Which one? scala.collection.mutable.Seq definitely exposes mutable properties.Boswell
The immutable one I and the OP are using in this example.Bearcat
S
2

It might be worth pointing out that while the Seq append item operator, :+, is left associative, the prepend operator, +:, is right associative.

So if you have a Seq collection with List elements:

scala> val SeqOfLists: Seq[List[String]] = Seq(List("foo", "bar"))
SeqOfLists: Seq[List[String]] = List(List(foo, bar))

and you want to add another "elem" to the Seq, appending is done this way:

scala> SeqOfLists :+ List("foo2", "bar2")
res0: Seq[List[String]] = List(List(foo, bar), List(foo2, bar2))

and prepending is done this way:

scala> List("foo2", "bar2") +: SeqOfLists
res1: Seq[List[String]] = List(List(foo2, bar2), List(foo, bar))

as described in the API doc:

A mnemonic for +: vs. :+ is: the COLon goes on the COLlection side.

Neglecting this when handling collections of collections can lead to unexpected results, i.e.:

scala> SeqOfLists +: List("foo2", "bar2")
res2: List[Object] = List(List(List(foo, bar)), foo2, bar2)
Saccharate answered 6/9, 2016 at 14:31 Comment(1)
@Yuval I can't comment yet on your post, so I am adding comment here. At time of writing this your append and prepend examples have customerList on the wrong side of the : (Colon). The collection being added to should be on the colon side of the operator.Saccharate

© 2022 - 2024 — McMap. All rights reserved.