Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add element to a Set from the Left (for readability)

Tags:

scala

Consider adding an element (from the left) to a Sequence using +: :

scala> val cl = Seq(1,2,3)
scala> 5 +: cl
res2: Seq[Int] = List(5, 1, 2, 3)

What (if any) is the equivalent for a Set ?

scala> val s = Set(1,2,3)
scala> 5 +: s
<console>:9: error: value +: is not a member of scala.collection.immutable.Set[Int]
              5 +: s

scala> 5.toInt + s
<console>:9: error: overloaded method value + with alternatives:
  (x: Double)Double <and>
  (x: Float)Float <and>
  (x: Long)Long <and>
  (x: Int)Int <and>
  (x: Char)Int <and>
  (x: Short)Int <and>
  (x: Byte)Int <and>
  (x: String)String
 cannot be applied to (scala.collection.immutable.Set[Int])
              5.toInt + s

Update I am well aware a Set does not retain order. The motivation is for readability of the code in certain cases - specifically when the Set is actually a long computation. The intent is to highlight the new element being added by placing it before that computation.

like image 461
WestCoastProjects Avatar asked Nov 27 '25 00:11

WestCoastProjects


2 Answers

Most implementations of Set don't preserve insertion order, so it doesn't make much sense to have such an operation. Of the immutable Sets only ListSet preserves (reverse) insertion order. So since it preserves reverse insertion order, ListSet has a "add to the left" method: the default + method. Yet it still doesn't have a "add to the other side" method.

If you simply want a +: method regardless of what it does, you can just add it as an extension method:

scala> implicit class PrependSet[A](val set: Set[A]) extends AnyVal {
     |   def +:(a: A) = set + a
     | }
defined class PrependSet

scala> 5 +: Set(1,2,3)
res0: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 5)
like image 169
Jasper-M Avatar answered Nov 29 '25 16:11

Jasper-M


There isn't. You can however wrap the element in a Set and concatenate.

scala> Set(5) ++ Set(1,2,3)
res4: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3)

This will of course only work if that element isn't already contained in the set.

However, you can't depend on the ordering in these sets. Mathematically, a set is an unordered collection of unique elements and you should treat them as such. See the documentation for sets for all the available operations on Sets. You might want to read about "Sorted sets" while you're at it.

like image 21
Christian Neverdal Avatar answered Nov 29 '25 16:11

Christian Neverdal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!