How to "update" an immutable element in an immutable set in Scala?

I have Set

elements that have their equality defined around the key, but other fields might be different ... So when I need to "update" this is what I tried:

object sandbox {

  case class K(val id: Int, val message: String) {
    override def equals(that: Any) = that match {
      case K(this.id, _) => true
      case _ => false
    }
    override def hashCode = this.id
    override def toString = "(" + id + "," + message + ")"
  }

  val s = Set(K(1, "a"), K(2, "b"))               //> s  : scala.collection.immutable.Set[test.sandbox.K] = Set((1,a), (2,b))
  val updatedElem = K(1, "c")                     //> updatedElem  : test.sandbox.K = (1,c)

  s + updatedElem                                 //> res0: scala.collection.immutable.Set[test.sandbox.K] = Set((1,a), (2,b))

  Set(updatedElem) | s                            //> res1: scala.collection.immutable.Set[test.sandbox.K] = Set((1,c), (2,b))
  }

      

Adding an item that already exists won't change the set, and removing it first and adding the updated one again seems kind of suboptimal.

The method union

keeps the elements of the set on the left, but this behavior is not documented; so I shouldn't rely on it.

So, is there something more obvious that I am missing? Should I rely on the actual behavior (and write a test in case it changes)? Or do I need to upgrade in two steps?

+3


source to share


1 answer


From my point of view, this is actually a problem of modeling concepts. The point is that equal objects must be truly equivalent ... otherwise you might consider some other structures. For example, why not try Map

which one displays id

in message

(or id

in K(id,message)

)? This seems much clearer in concepts and then you can use .updated(1,"c")

to update it.



+5


source







All Articles