Updating a tuple?

n/a

You’ll need to use your own mutable data structure. Like a case class with two vars.

Firstly, I would recommend always defaulting to immutable references (i.e., use “val” instead of “var” unless you have a good reason for it).

Secondly, you say you want to increment only a single tuple, but your code is making the change for a set of values.

Depending on your desired performance characteristics, one approach would be to use the “map” higher-order function:

val myList = List((“J”, 10), (“D”, 60), (“M”, 20))

val tempSet = Set(“J”, “D”, “M”)

val updatedList = myList.map(x => if(tempSet.contains(x._1)) (x._1, x._2 +1) else x)

There are many ways to approach this problem, and this one is straightforward, but not the most performant; however, it’s good enough for many cases.

Regards,

Will

@wrbriggs response accounts for this, but in general I also recommend staying away from .get unless you’ve decorated it with some additional measure to catch errors.

If you change the code to:

val myList = List(("J", 10), ("D", 60), ("M", 20))
val tempSet = Set("J","D","M")

for (el <- tempSet) {
  val newNum = myList.find(x => x._1 == el).get._2
  println(newNum)
}

You get output:

10
60
20

However, when you add an additional item to tempSet:

val myList = List(("J", 10), ("D", 60), ("M", 20))
val tempSet = Set("J","D","M", "Z")

for (el <- tempSet) {
  val newNum = myList.find(x => x._1 == el).get._2
  println(newNum)
}

You get a java.util.NoSuchElementException: None.get exception, because it can’t find “Z”. The .find returns an Option[A], and .get expects the Option to be non-empty.

Note that tuples have copy, and I think x.copy(x._2 = x._2 + 1) is a bit easier to read than (x._1, x._2 +1), even though it’s more characters.

On a longer tuple, using copy would be shorter, too.

@SethTisue I use copy all the time with case classes; I had no idea tuples supported it, too! Thanks for the tip!

Regards,
Will

May we convince you to use a Map instead? Maps let you deal with key-value pairs:

val map1 = Map("J" -> 10, "D" -> 60, "M" -> 20, /* others */)
val set = Set("J", "D", "M")

val map2 = map1.map {
  case (k, v) if set.contains(k) => (k, v + 1)
  case other => other
}
1 Like