Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: map just first element in tuple

Tags:

tuples

scala

I want to use some function on tuple, which returns tuple with only first element transformed and other elements unchanged.

This is naive version for Tuple2:

def mapFirst[T, U, R](tuple: (T, U))(f: T => R): (R, U) = tuple match {
     |   case (x, y) => f(x) -> y
     | }

mapFirst((1, 2))(_ * 5) // returns (5, 2)

Though, it doesn't feel native, what I want is to write it this way:

(1, 2).mapFirst(_ * 5)

I wrote implicit conversion then:

class RichTuple[T, U](tuple: (T, U)) {
  def mapFirst[R](f: T => R): (R, U) = tuple match {
    case (x, y) => f(x) -> y
  }
}

implicit def tuple2RichTuple[T, U](tuple: (T, U)): RichTuple[T, U] = new RichTuple(tuple)

(1, 2).mapFirst(_ * 5)

Then, when I'll want to map just second element or first element on Tuple3, I'll have to write same boilerplate again. Is there some library which has such methods built-in?

like image 719
Evgeny Veretennikov Avatar asked Sep 06 '25 20:09

Evgeny Veretennikov


2 Answers

You can use shapeless tuple functions:

import shapeless._
import syntax.std.tuple._
val x=(1,2,3)
val y=x.updatedAt(0,x.head*5)
// y= (5,2,3)
like image 165
Arnon Rotem-Gal-Oz Avatar answered Sep 10 '25 07:09

Arnon Rotem-Gal-Oz


We are able to use _1 as tuple's field. One more solution, just using standard library:

val x = (1, 2, 3)
val y = x.copy(_1 = x._1 * 5)
like image 28
Evgeny Veretennikov Avatar answered Sep 10 '25 09:09

Evgeny Veretennikov