Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a tuple argument the best way?

How to pass a tuple argument the best way ?

Example:

def foo(...): (Int, Int) = ...  def bar(a: Int, b: Int) = ... 

Now I would like to pass the output of foo to bar. This can be achieved with:

val fooResult = foo(...) bar(fooResult._1, fooResult._2) 

This approach looks a bit ugly, especially when we deal with a n-tuple with n > 2. Also we have to store the result of foo in an extra value, because otherwise foo has to be executed more than once using bar(foo._1, foo._2).

Is there a better way to pass through the tuple as argument ?

like image 998
John Threepwood Avatar asked Sep 01 '12 19:09

John Threepwood


People also ask

How do you pass a tuple as an argument?

This method of passing a tuple as an argument to a function involves unpacking method. Unpacking in Python uses *args syntax. As functions can take an arbitrary number of arguments, we use the unpacking operator * to unpack the single argument into multiple arguments.

Which is the efficient way to change a value in tuple?

Once a tuple is created, you cannot change its values. Tuples are unchangeable, or immutable as it also is called. But there is a workaround. You can convert the tuple into a list, change the list, and convert the list back into a tuple.


2 Answers

There is a special tupled method available for every function:

val bar2 = (bar _).tupled  // or Function.tupled(bar _) 

bar2 takes a tuple of (Int, Int) (same as bar arguments). Now you can say:

bar2(foo()) 

If your methods were actually functions (notice the val keyword) the syntax is much more pleasant:

val bar = (a: Int, b: Int) => //... bar.tupled(foo()) 

See also

  • How to apply a function to a tuple?
like image 120
Tomasz Nurkiewicz Avatar answered Oct 04 '22 00:10

Tomasz Nurkiewicz


It is worth also knowing about

foo(...) match { case (a,b) => bar(a,b) } 

as an alternative that doesn't require you to explicitly create a temporary fooResult. It's a good compromise when speed and lack of clutter are both important. You can create a function with bar _ and then convert it to take a single tuple argument with .tupled, but this creates a two new function objects each time you call the pair; you could store the result, but that could clutter your code unnecessarily.

For everyday use (i.e. this is not the performance-limiting part of your code), you can just

(bar _).tupled(foo(...)) 

in line. Sure, you create two extra function objects, but you most likely just created the tuple also, so you don't care that much, right?

like image 40
Rex Kerr Avatar answered Oct 04 '22 02:10

Rex Kerr